forked from vikunja/vikunja
Update swag
This commit is contained in:
parent
f603b41d99
commit
a6fbf85073
2
Makefile
2
Makefile
|
@ -190,7 +190,7 @@ do-the-swag:
|
||||||
@hash swag > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash swag > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
go install $(GOFLAGS) github.com/swaggo/swag/cmd/swag; \
|
go install $(GOFLAGS) github.com/swaggo/swag/cmd/swag; \
|
||||||
fi
|
fi
|
||||||
swag init -g pkg/routes/routes.go -o ./pkg/swagger;
|
swag init --parseVendor --parseDependency -g pkg/routes/routes.go -o ./pkg/swagger;
|
||||||
# Fix the generated swagger file, currently a workaround until swaggo can properly use go mod
|
# Fix the generated swagger file, currently a workaround until swaggo can properly use go mod
|
||||||
sed -i '/"definitions": {/a "code.vikunja.io.web.HTTPError": {"type": "object","properties": {"code": {"type": "integer"},"message": {"type": "string"}}},' pkg/swagger/docs.go;
|
sed -i '/"definitions": {/a "code.vikunja.io.web.HTTPError": {"type": "object","properties": {"code": {"type": "integer"},"message": {"type": "string"}}},' pkg/swagger/docs.go;
|
||||||
sed -i 's/code.vikunja.io\/web.HTTPError/code.vikunja.io.web.HTTPError/g' pkg/swagger/docs.go;
|
sed -i 's/code.vikunja.io\/web.HTTPError/code.vikunja.io.web.HTTPError/g' pkg/swagger/docs.go;
|
||||||
|
|
11
go.mod
11
go.mod
|
@ -30,8 +30,8 @@ require (
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
||||||
github.com/garyburd/redigo v1.6.0 // indirect
|
github.com/garyburd/redigo v1.6.0 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
github.com/go-openapi/spec v0.19.5 // indirect
|
||||||
github.com/go-openapi/spec v0.19.4 // indirect
|
github.com/go-openapi/swag v0.19.7 // indirect
|
||||||
github.com/go-redis/redis v6.15.2+incompatible
|
github.com/go-redis/redis v6.15.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-xorm/builder v0.3.4
|
github.com/go-xorm/builder v0.3.4
|
||||||
|
@ -68,20 +68,19 @@ require (
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/viper v1.3.2
|
github.com/spf13/viper v1.3.2
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/swaggo/swag v1.6.3
|
github.com/swaggo/swag v1.6.5
|
||||||
github.com/ulule/limiter/v3 v3.3.0
|
github.com/ulule/limiter/v3 v3.3.0
|
||||||
github.com/urfave/cli v1.22.2 // indirect
|
|
||||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad
|
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
|
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d // indirect
|
golang.org/x/tools v0.0.0-20200125223703-d33eef8e6825 // indirect
|
||||||
google.golang.org/appengine v1.5.0 // indirect
|
google.golang.org/appengine v1.5.0 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/testfixtures.v2 v2.5.3
|
gopkg.in/testfixtures.v2 v2.5.3
|
||||||
gopkg.in/yaml.v2 v2.2.7 // indirect
|
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a
|
||||||
src.techknowlogick.com/xgo v0.0.0-20190507142556-a5b29ecb0ff4
|
src.techknowlogick.com/xgo v0.0.0-20190507142556-a5b29ecb0ff4
|
||||||
src.techknowlogick.com/xormigrate v0.0.0-20190321151057-24497c23c09c
|
src.techknowlogick.com/xormigrate v0.0.0-20190321151057-24497c23c09c
|
||||||
|
|
21
go.sum
21
go.sum
|
@ -77,10 +77,14 @@ github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k
|
||||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
|
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
|
||||||
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||||
|
github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
|
||||||
|
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
|
||||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
|
github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s=
|
||||||
|
github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||||
github.com/go-redis/redis v6.14.0+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.14.0+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
|
@ -260,8 +264,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||||
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
||||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
||||||
github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=
|
github.com/swaggo/swag v1.6.5 h1:2C+t+xyK6p1sujqncYO/VnMvPZcBJjNdKKyxbOdAW8o=
|
||||||
github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio=
|
github.com/swaggo/swag v1.6.5/go.mod h1:Y7ZLSS0d0DdxhWGVhQdu+Bu1QhaF5k0RD7FKdiAykeY=
|
||||||
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||||
|
@ -291,11 +295,13 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
||||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
|
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
|
||||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
||||||
|
@ -352,9 +358,9 @@ golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e h1:ZlQjfVdpDxeqxRfmO30CdqWWzTvgRCj0MxaUVfxEG1k=
|
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e h1:ZlQjfVdpDxeqxRfmO30CdqWWzTvgRCj0MxaUVfxEG1k=
|
||||||
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d h1:/iIZNFGxc/a7C3yWjGcnboV+Tkc7mxr+p6fDztwoxuM=
|
golang.org/x/tools v0.0.0-20200125223703-d33eef8e6825 h1:aNQeSIHKi0RWpKA5NO0CqyLjx6Beh5l0LLUEnndEjz0=
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20200125223703-d33eef8e6825/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
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=
|
||||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
@ -384,8 +390,9 @@ gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/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.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
src.techknowlogick.com/xgo v0.0.0-20190507142556-a5b29ecb0ff4 h1:DZKMg4qnT7UIyB5ZaC6ZqltF2K5KhA1oQ2PdxOLZ3jg=
|
src.techknowlogick.com/xgo v0.0.0-20190507142556-a5b29ecb0ff4 h1:DZKMg4qnT7UIyB5ZaC6ZqltF2K5KhA1oQ2PdxOLZ3jg=
|
||||||
|
|
|
@ -38,7 +38,7 @@ type LinkShareToken struct {
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param share path string true "The share hash"
|
// @Param share path string true "The share hash"
|
||||||
// @Success 200 {object} v1.Token "The valid jwt auth token."
|
// @Success 200 {object} v1.Token "The valid jwt auth token."
|
||||||
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid link share object provided."
|
// @Failure 400 {object} web.HTTPError "Invalid link share object provided."
|
||||||
// @Failure 500 {object} models.Message "Internal error"
|
// @Failure 500 {object} models.Message "Internal error"
|
||||||
// @Router /shares/{share}/auth [post]
|
// @Router /shares/{share}/auth [post]
|
||||||
func AuthenticateLinkShare(c echo.Context) error {
|
func AuthenticateLinkShare(c echo.Context) error {
|
||||||
|
|
5
vendor/github.com/go-openapi/spec/.golangci.yml
generated
vendored
5
vendor/github.com/go-openapi/spec/.golangci.yml
generated
vendored
|
@ -21,3 +21,8 @@ linters:
|
||||||
- lll
|
- lll
|
||||||
- gochecknoinits
|
- gochecknoinits
|
||||||
- gochecknoglobals
|
- gochecknoglobals
|
||||||
|
- funlen
|
||||||
|
- godox
|
||||||
|
- gocognit
|
||||||
|
- whitespace
|
||||||
|
- wsl
|
||||||
|
|
7
vendor/github.com/go-openapi/spec/expander.go
generated
vendored
7
vendor/github.com/go-openapi/spec/expander.go
generated
vendored
|
@ -452,11 +452,12 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if pathItem.Ref.String() != "" {
|
if pathItem.Ref.String() != "" {
|
||||||
var err error
|
transitiveResolver, err := resolver.transitiveResolver(basePath, pathItem.Ref)
|
||||||
resolver, err = resolver.transitiveResolver(basePath, pathItem.Ref)
|
if transitiveResolver.shouldStopOnError(err) {
|
||||||
if resolver.shouldStopOnError(err) {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
basePath = transitiveResolver.updateBasePath(resolver, basePath)
|
||||||
|
resolver = transitiveResolver
|
||||||
}
|
}
|
||||||
pathItem.Ref = Ref{}
|
pathItem.Ref = Ref{}
|
||||||
|
|
||||||
|
|
7
vendor/github.com/go-openapi/spec/go.mod
generated
vendored
7
vendor/github.com/go-openapi/spec/go.mod
generated
vendored
|
@ -4,14 +4,9 @@ require (
|
||||||
github.com/go-openapi/jsonpointer v0.19.3
|
github.com/go-openapi/jsonpointer v0.19.3
|
||||||
github.com/go-openapi/jsonreference v0.19.2
|
github.com/go-openapi/jsonreference v0.19.2
|
||||||
github.com/go-openapi/swag v0.19.5
|
github.com/go-openapi/swag v0.19.5
|
||||||
github.com/kr/pty v1.1.5 // indirect
|
|
||||||
github.com/stretchr/objx v0.2.0 // indirect
|
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/stretchr/testify v1.3.0
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect
|
gopkg.in/yaml.v2 v2.2.4
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.2.2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
29
vendor/github.com/go-openapi/spec/go.sum
generated
vendored
29
vendor/github.com/go-openapi/spec/go.sum
generated
vendored
|
@ -1,5 +1,3 @@
|
||||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
|
||||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
|
||||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
|
@ -7,20 +5,12 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/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/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
|
||||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.0 h1:FTUMcX77w5rQkClIzDtTxvn6Bsa894CcrzNj2MMfeg8=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
|
github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
|
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
|
||||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||||
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
|
|
||||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
|
||||||
github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
|
github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
|
||||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||||
|
@ -28,11 +18,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||||
|
@ -40,35 +27,23 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
|
||||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/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-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/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.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||||
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
1
vendor/github.com/go-openapi/spec/ref.go
generated
vendored
1
vendor/github.com/go-openapi/spec/ref.go
generated
vendored
|
@ -68,6 +68,7 @@ func (r *Ref) IsValidURI(basepaths ...string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.HasFullURL {
|
if r.HasFullURL {
|
||||||
|
//#nosec
|
||||||
rr, err := http.Get(v)
|
rr, err := http.Get(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
|
7
vendor/github.com/go-openapi/spec/schema_loader.go
generated
vendored
7
vendor/github.com/go-openapi/spec/schema_loader.go
generated
vendored
|
@ -86,12 +86,7 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoad
|
||||||
newOptions := r.options
|
newOptions := r.options
|
||||||
newOptions.RelativeBase = rootURL.String()
|
newOptions.RelativeBase = rootURL.String()
|
||||||
debugLog("setting new root: %s", newOptions.RelativeBase)
|
debugLog("setting new root: %s", newOptions.RelativeBase)
|
||||||
resolver, err := defaultSchemaLoader(root, newOptions, r.cache, r.context)
|
return defaultSchemaLoader(root, newOptions, r.cache, r.context)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolver, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string {
|
func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string {
|
||||||
|
|
16
vendor/github.com/go-openapi/swag/convert.go
generated
vendored
16
vendor/github.com/go-openapi/swag/convert.go
generated
vendored
|
@ -88,7 +88,7 @@ func ConvertFloat64(str string) (float64, error) {
|
||||||
return strconv.ParseFloat(str, 64)
|
return strconv.ParseFloat(str, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertInt8 turn a string into int8 boolean
|
// ConvertInt8 turn a string into an int8
|
||||||
func ConvertInt8(str string) (int8, error) {
|
func ConvertInt8(str string) (int8, error) {
|
||||||
i, err := strconv.ParseInt(str, 10, 8)
|
i, err := strconv.ParseInt(str, 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -97,7 +97,7 @@ func ConvertInt8(str string) (int8, error) {
|
||||||
return int8(i), nil
|
return int8(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertInt16 turn a string into a int16
|
// ConvertInt16 turn a string into an int16
|
||||||
func ConvertInt16(str string) (int16, error) {
|
func ConvertInt16(str string) (int16, error) {
|
||||||
i, err := strconv.ParseInt(str, 10, 16)
|
i, err := strconv.ParseInt(str, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -106,7 +106,7 @@ func ConvertInt16(str string) (int16, error) {
|
||||||
return int16(i), nil
|
return int16(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertInt32 turn a string into a int32
|
// ConvertInt32 turn a string into an int32
|
||||||
func ConvertInt32(str string) (int32, error) {
|
func ConvertInt32(str string) (int32, error) {
|
||||||
i, err := strconv.ParseInt(str, 10, 32)
|
i, err := strconv.ParseInt(str, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,12 +115,12 @@ func ConvertInt32(str string) (int32, error) {
|
||||||
return int32(i), nil
|
return int32(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertInt64 turn a string into a int64
|
// ConvertInt64 turn a string into an int64
|
||||||
func ConvertInt64(str string) (int64, error) {
|
func ConvertInt64(str string) (int64, error) {
|
||||||
return strconv.ParseInt(str, 10, 64)
|
return strconv.ParseInt(str, 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertUint8 turn a string into a uint8
|
// ConvertUint8 turn a string into an uint8
|
||||||
func ConvertUint8(str string) (uint8, error) {
|
func ConvertUint8(str string) (uint8, error) {
|
||||||
i, err := strconv.ParseUint(str, 10, 8)
|
i, err := strconv.ParseUint(str, 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -129,7 +129,7 @@ func ConvertUint8(str string) (uint8, error) {
|
||||||
return uint8(i), nil
|
return uint8(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertUint16 turn a string into a uint16
|
// ConvertUint16 turn a string into an uint16
|
||||||
func ConvertUint16(str string) (uint16, error) {
|
func ConvertUint16(str string) (uint16, error) {
|
||||||
i, err := strconv.ParseUint(str, 10, 16)
|
i, err := strconv.ParseUint(str, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -138,7 +138,7 @@ func ConvertUint16(str string) (uint16, error) {
|
||||||
return uint16(i), nil
|
return uint16(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertUint32 turn a string into a uint32
|
// ConvertUint32 turn a string into an uint32
|
||||||
func ConvertUint32(str string) (uint32, error) {
|
func ConvertUint32(str string) (uint32, error) {
|
||||||
i, err := strconv.ParseUint(str, 10, 32)
|
i, err := strconv.ParseUint(str, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -147,7 +147,7 @@ func ConvertUint32(str string) (uint32, error) {
|
||||||
return uint32(i), nil
|
return uint32(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertUint64 turn a string into a uint64
|
// ConvertUint64 turn a string into an uint64
|
||||||
func ConvertUint64(str string) (uint64, error) {
|
func ConvertUint64(str string) (uint64, error) {
|
||||||
return strconv.ParseUint(str, 10, 64)
|
return strconv.ParseUint(str, 10, 64)
|
||||||
}
|
}
|
||||||
|
|
60
vendor/github.com/go-openapi/swag/convert_types.go
generated
vendored
60
vendor/github.com/go-openapi/swag/convert_types.go
generated
vendored
|
@ -181,12 +181,12 @@ func IntValueMap(src map[string]*int) map[string]int {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int32 returns a pointer to of the int64 value passed in.
|
// Int32 returns a pointer to of the int32 value passed in.
|
||||||
func Int32(v int32) *int32 {
|
func Int32(v int32) *int32 {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int32Value returns the value of the int64 pointer passed in or
|
// Int32Value returns the value of the int32 pointer passed in or
|
||||||
// 0 if the pointer is nil.
|
// 0 if the pointer is nil.
|
||||||
func Int32Value(v *int32) int32 {
|
func Int32Value(v *int32) int32 {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
|
@ -195,7 +195,7 @@ func Int32Value(v *int32) int32 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int32Slice converts a slice of int64 values into a slice of
|
// Int32Slice converts a slice of int32 values into a slice of
|
||||||
// int32 pointers
|
// int32 pointers
|
||||||
func Int32Slice(src []int32) []*int32 {
|
func Int32Slice(src []int32) []*int32 {
|
||||||
dst := make([]*int32, len(src))
|
dst := make([]*int32, len(src))
|
||||||
|
@ -299,13 +299,13 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint returns a pouinter to of the uint value passed in.
|
// Uint returns a pointer to of the uint value passed in.
|
||||||
func Uint(v uint) *uint {
|
func Uint(v uint) *uint {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// UintValue returns the value of the uint pouinter passed in or
|
// UintValue returns the value of the uint pointer passed in or
|
||||||
// 0 if the pouinter is nil.
|
// 0 if the pointer is nil.
|
||||||
func UintValue(v *uint) uint {
|
func UintValue(v *uint) uint {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
return *v
|
return *v
|
||||||
|
@ -313,8 +313,8 @@ func UintValue(v *uint) uint {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// UintSlice converts a slice of uint values uinto a slice of
|
// UintSlice converts a slice of uint values into a slice of
|
||||||
// uint pouinters
|
// uint pointers
|
||||||
func UintSlice(src []uint) []*uint {
|
func UintSlice(src []uint) []*uint {
|
||||||
dst := make([]*uint, len(src))
|
dst := make([]*uint, len(src))
|
||||||
for i := 0; i < len(src); i++ {
|
for i := 0; i < len(src); i++ {
|
||||||
|
@ -323,7 +323,7 @@ func UintSlice(src []uint) []*uint {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// UintValueSlice converts a slice of uint pouinters uinto a slice of
|
// UintValueSlice converts a slice of uint pointers into a slice of
|
||||||
// uint values
|
// uint values
|
||||||
func UintValueSlice(src []*uint) []uint {
|
func UintValueSlice(src []*uint) []uint {
|
||||||
dst := make([]uint, len(src))
|
dst := make([]uint, len(src))
|
||||||
|
@ -335,8 +335,8 @@ func UintValueSlice(src []*uint) []uint {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// UintMap converts a string map of uint values uinto a string
|
// UintMap converts a string map of uint values into a string
|
||||||
// map of uint pouinters
|
// map of uint pointers
|
||||||
func UintMap(src map[string]uint) map[string]*uint {
|
func UintMap(src map[string]uint) map[string]*uint {
|
||||||
dst := make(map[string]*uint)
|
dst := make(map[string]*uint)
|
||||||
for k, val := range src {
|
for k, val := range src {
|
||||||
|
@ -346,7 +346,7 @@ func UintMap(src map[string]uint) map[string]*uint {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// UintValueMap converts a string map of uint pouinters uinto a string
|
// UintValueMap converts a string map of uint pointers into a string
|
||||||
// map of uint values
|
// map of uint values
|
||||||
func UintValueMap(src map[string]*uint) map[string]uint {
|
func UintValueMap(src map[string]*uint) map[string]uint {
|
||||||
dst := make(map[string]uint)
|
dst := make(map[string]uint)
|
||||||
|
@ -358,13 +358,13 @@ func UintValueMap(src map[string]*uint) map[string]uint {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32 returns a pouinter to of the uint64 value passed in.
|
// Uint32 returns a pointer to of the uint32 value passed in.
|
||||||
func Uint32(v uint32) *uint32 {
|
func Uint32(v uint32) *uint32 {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32Value returns the value of the uint64 pouinter passed in or
|
// Uint32Value returns the value of the uint32 pointer passed in or
|
||||||
// 0 if the pouinter is nil.
|
// 0 if the pointer is nil.
|
||||||
func Uint32Value(v *uint32) uint32 {
|
func Uint32Value(v *uint32) uint32 {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
return *v
|
return *v
|
||||||
|
@ -372,8 +372,8 @@ func Uint32Value(v *uint32) uint32 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32Slice converts a slice of uint64 values uinto a slice of
|
// Uint32Slice converts a slice of uint32 values into a slice of
|
||||||
// uint32 pouinters
|
// uint32 pointers
|
||||||
func Uint32Slice(src []uint32) []*uint32 {
|
func Uint32Slice(src []uint32) []*uint32 {
|
||||||
dst := make([]*uint32, len(src))
|
dst := make([]*uint32, len(src))
|
||||||
for i := 0; i < len(src); i++ {
|
for i := 0; i < len(src); i++ {
|
||||||
|
@ -382,7 +382,7 @@ func Uint32Slice(src []uint32) []*uint32 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of
|
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
|
||||||
// uint32 values
|
// uint32 values
|
||||||
func Uint32ValueSlice(src []*uint32) []uint32 {
|
func Uint32ValueSlice(src []*uint32) []uint32 {
|
||||||
dst := make([]uint32, len(src))
|
dst := make([]uint32, len(src))
|
||||||
|
@ -394,8 +394,8 @@ func Uint32ValueSlice(src []*uint32) []uint32 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32Map converts a string map of uint32 values uinto a string
|
// Uint32Map converts a string map of uint32 values into a string
|
||||||
// map of uint32 pouinters
|
// map of uint32 pointers
|
||||||
func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
||||||
dst := make(map[string]*uint32)
|
dst := make(map[string]*uint32)
|
||||||
for k, val := range src {
|
for k, val := range src {
|
||||||
|
@ -405,7 +405,7 @@ func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32ValueMap converts a string map of uint32 pouinters uinto a string
|
// Uint32ValueMap converts a string map of uint32 pointers into a string
|
||||||
// map of uint32 values
|
// map of uint32 values
|
||||||
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
||||||
dst := make(map[string]uint32)
|
dst := make(map[string]uint32)
|
||||||
|
@ -417,13 +417,13 @@ func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64 returns a pouinter to of the uint64 value passed in.
|
// Uint64 returns a pointer to of the uint64 value passed in.
|
||||||
func Uint64(v uint64) *uint64 {
|
func Uint64(v uint64) *uint64 {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64Value returns the value of the uint64 pouinter passed in or
|
// Uint64Value returns the value of the uint64 pointer passed in or
|
||||||
// 0 if the pouinter is nil.
|
// 0 if the pointer is nil.
|
||||||
func Uint64Value(v *uint64) uint64 {
|
func Uint64Value(v *uint64) uint64 {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
return *v
|
return *v
|
||||||
|
@ -431,8 +431,8 @@ func Uint64Value(v *uint64) uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64Slice converts a slice of uint64 values uinto a slice of
|
// Uint64Slice converts a slice of uint64 values into a slice of
|
||||||
// uint64 pouinters
|
// uint64 pointers
|
||||||
func Uint64Slice(src []uint64) []*uint64 {
|
func Uint64Slice(src []uint64) []*uint64 {
|
||||||
dst := make([]*uint64, len(src))
|
dst := make([]*uint64, len(src))
|
||||||
for i := 0; i < len(src); i++ {
|
for i := 0; i < len(src); i++ {
|
||||||
|
@ -441,7 +441,7 @@ func Uint64Slice(src []uint64) []*uint64 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of
|
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
|
||||||
// uint64 values
|
// uint64 values
|
||||||
func Uint64ValueSlice(src []*uint64) []uint64 {
|
func Uint64ValueSlice(src []*uint64) []uint64 {
|
||||||
dst := make([]uint64, len(src))
|
dst := make([]uint64, len(src))
|
||||||
|
@ -453,8 +453,8 @@ func Uint64ValueSlice(src []*uint64) []uint64 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64Map converts a string map of uint64 values uinto a string
|
// Uint64Map converts a string map of uint64 values into a string
|
||||||
// map of uint64 pouinters
|
// map of uint64 pointers
|
||||||
func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
||||||
dst := make(map[string]*uint64)
|
dst := make(map[string]*uint64)
|
||||||
for k, val := range src {
|
for k, val := range src {
|
||||||
|
@ -464,7 +464,7 @@ func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64ValueMap converts a string map of uint64 pouinters uinto a string
|
// Uint64ValueMap converts a string map of uint64 pointers into a string
|
||||||
// map of uint64 values
|
// map of uint64 values
|
||||||
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
|
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
|
||||||
dst := make(map[string]uint64)
|
dst := make(map[string]uint64)
|
||||||
|
|
4
vendor/github.com/go-openapi/swag/go.mod
generated
vendored
4
vendor/github.com/go-openapi/swag/go.mod
generated
vendored
|
@ -6,9 +6,11 @@ require (
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/stretchr/testify v1.3.0
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.2
|
gopkg.in/yaml.v2 v2.2.4
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
||||||
|
|
||||||
replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1
|
replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
4
vendor/github.com/go-openapi/swag/go.sum
generated
vendored
4
vendor/github.com/go-openapi/swag/go.sum
generated
vendored
|
@ -16,5 +16,5 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
8
vendor/github.com/go-openapi/swag/json.go
generated
vendored
8
vendor/github.com/go-openapi/swag/json.go
generated
vendored
|
@ -51,7 +51,7 @@ type ejUnmarshaler interface {
|
||||||
UnmarshalEasyJSON(w *jlexer.Lexer)
|
UnmarshalEasyJSON(w *jlexer.Lexer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller
|
// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler
|
||||||
// so it takes the fastest option available.
|
// so it takes the fastest option available.
|
||||||
func WriteJSON(data interface{}) ([]byte, error) {
|
func WriteJSON(data interface{}) ([]byte, error) {
|
||||||
if d, ok := data.(ejMarshaler); ok {
|
if d, ok := data.(ejMarshaler); ok {
|
||||||
|
@ -65,8 +65,8 @@ func WriteJSON(data interface{}) ([]byte, error) {
|
||||||
return json.Marshal(data)
|
return json.Marshal(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller
|
// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler
|
||||||
// so it takes the fastes option available
|
// so it takes the fastest option available
|
||||||
func ReadJSON(data []byte, value interface{}) error {
|
func ReadJSON(data []byte, value interface{}) error {
|
||||||
trimmedData := bytes.Trim(data, "\x00")
|
trimmedData := bytes.Trim(data, "\x00")
|
||||||
if d, ok := value.(ejUnmarshaler); ok {
|
if d, ok := value.(ejUnmarshaler); ok {
|
||||||
|
@ -189,7 +189,7 @@ func FromDynamicJSON(data, target interface{}) error {
|
||||||
return json.Unmarshal(b, target)
|
return json.Unmarshal(b, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameProvider represents an object capabale of translating from go property names
|
// NameProvider represents an object capable of translating from go property names
|
||||||
// to json property names
|
// to json property names
|
||||||
// This type is thread-safe.
|
// This type is thread-safe.
|
||||||
type NameProvider struct {
|
type NameProvider struct {
|
||||||
|
|
2
vendor/github.com/go-xorm/xorm/go.mod
generated
vendored
2
vendor/github.com/go-xorm/xorm/go.mod
generated
vendored
|
@ -22,3 +22,5 @@ require (
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/stretchr/testify.v1 v1.2.2
|
gopkg.in/stretchr/testify.v1 v1.2.2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
2
vendor/github.com/hashicorp/hcl/go.mod
generated
vendored
2
vendor/github.com/hashicorp/hcl/go.mod
generated
vendored
|
@ -1,3 +1,5 @@
|
||||||
module github.com/hashicorp/hcl
|
module github.com/hashicorp/hcl
|
||||||
|
|
||||||
require github.com/davecgh/go-spew v1.1.1
|
require github.com/davecgh/go-spew v1.1.1
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
2
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
2
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
|
@ -1,3 +1,3 @@
|
||||||
module github.com/prometheus/procfs
|
module github.com/prometheus/procfs
|
||||||
|
|
||||||
go 1.12
|
go 1.13
|
||||||
|
|
2
vendor/github.com/spf13/viper/go.mod
generated
vendored
2
vendor/github.com/spf13/viper/go.mod
generated
vendored
|
@ -22,3 +22,5 @@ require (
|
||||||
golang.org/x/text v0.3.0 // indirect
|
golang.org/x/text v0.3.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.2
|
gopkg.in/yaml.v2 v2.2.2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
1
vendor/github.com/swaggo/swag/.travis.yml
generated
vendored
1
vendor/github.com/swaggo/swag/.travis.yml
generated
vendored
|
@ -2,7 +2,6 @@ language: go
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.10.x
|
|
||||||
- 1.11.x
|
- 1.11.x
|
||||||
- 1.12.x
|
- 1.12.x
|
||||||
|
|
||||||
|
|
13
vendor/github.com/swaggo/swag/Makefile
generated
vendored
13
vendor/github.com/swaggo/swag/Makefile
generated
vendored
|
@ -9,6 +9,7 @@ GOTEST:=$(GOCMD) test
|
||||||
GOGET:=$(GOCMD) get
|
GOGET:=$(GOCMD) get
|
||||||
GOLIST:=$(GOCMD) list
|
GOLIST:=$(GOCMD) list
|
||||||
GOVET:=$(GOCMD) vet
|
GOVET:=$(GOCMD) vet
|
||||||
|
GOPATH:=$(shell $(GOCMD) env GOPATH)
|
||||||
u := $(if $(update),-u)
|
u := $(if $(update),-u)
|
||||||
|
|
||||||
BINARY_NAME:=swag
|
BINARY_NAME:=swag
|
||||||
|
@ -53,16 +54,20 @@ clean:
|
||||||
|
|
||||||
.PHONY: deps
|
.PHONY: deps
|
||||||
deps:
|
deps:
|
||||||
$(GOGET) ${u} -d
|
$(GOGET) github.com/swaggo/cli
|
||||||
|
$(GOGET) github.com/ghodss/yaml
|
||||||
|
$(GOGET) github.com/gin-gonic/gin
|
||||||
|
$(GOGET) github.com/KyleBanks/depth
|
||||||
|
$(GOGET) github.com/go-openapi/jsonreference
|
||||||
|
$(GOGET) github.com/go-openapi/spec
|
||||||
$(GOGET) github.com/stretchr/testify/assert
|
$(GOGET) github.com/stretchr/testify/assert
|
||||||
$(GOGET) github.com/alecthomas/template
|
$(GOGET) github.com/alecthomas/template
|
||||||
|
$(GOGET) golang.org/x/tools/go/loader
|
||||||
|
|
||||||
.PHONY: devel-deps
|
.PHONY: devel-deps
|
||||||
devel-deps:
|
devel-deps:
|
||||||
GO111MODULE=off $(GOGET) -v -u \
|
GO111MODULE=off $(GOGET) -v -u \
|
||||||
golang.org/x/lint/golint \
|
golang.org/x/lint/golint
|
||||||
github.com/swaggo/swag/cmd/swag \
|
|
||||||
github.com/swaggo/swag/gen
|
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: devel-deps
|
lint: devel-deps
|
||||||
|
|
8
vendor/github.com/swaggo/swag/README.md
generated
vendored
8
vendor/github.com/swaggo/swag/README.md
generated
vendored
|
@ -45,7 +45,7 @@ $ go get -u github.com/swaggo/swag/cmd/swag
|
||||||
```
|
```
|
||||||
To build from source you need [Go](https://golang.org/dl/) (1.9 or newer).
|
To build from source you need [Go](https://golang.org/dl/) (1.9 or newer).
|
||||||
|
|
||||||
Or download the pre-compiled binaries binray form [release page](https://github.com/swaggo/swag/releases).
|
Or download a pre-compiled binary from the [release page](https://github.com/swaggo/swag/releases).
|
||||||
|
|
||||||
3. Run `swag init` in the project's root folder which contains the `main.go` file. This will parse your comments and generate the required files (`docs` folder and `docs/docs.go`).
|
3. Run `swag init` in the project's root folder which contains the `main.go` file. This will parse your comments and generate the required files (`docs` folder and `docs/docs.go`).
|
||||||
```sh
|
```sh
|
||||||
|
@ -71,7 +71,7 @@ OPTIONS:
|
||||||
--generalInfo value, -g value Go file path in which 'swagger general API Info' is written (default: "main.go")
|
--generalInfo value, -g value Go file path in which 'swagger general API Info' is written (default: "main.go")
|
||||||
--dir value, -d value Directory you want to parse (default: "./")
|
--dir value, -d value Directory you want to parse (default: "./")
|
||||||
--propertyStrategy value, -p value Property Naming Strategy like snakecase,camelcase,pascalcase (default: "camelcase")
|
--propertyStrategy value, -p value Property Naming Strategy like snakecase,camelcase,pascalcase (default: "camelcase")
|
||||||
--output value, -o value Output directory for al the generated files(swagger.json, swagger.yaml and doc.go) (default: "./docs")
|
--output value, -o value Output directory for all the generated files(swagger.json, swagger.yaml and doc.go) (default: "./docs")
|
||||||
--parseVendor Parse go files in 'vendor' folder, disabled by default
|
--parseVendor Parse go files in 'vendor' folder, disabled by default
|
||||||
--parseDependency Parse go files in outside dependency folder, disabled by default
|
--parseDependency Parse go files in outside dependency folder, disabled by default
|
||||||
```
|
```
|
||||||
|
@ -277,7 +277,7 @@ func (c *Controller) ListAccounts(ctx *gin.Context) {
|
||||||
$ swag init
|
$ swag init
|
||||||
```
|
```
|
||||||
|
|
||||||
4.Run your app, and browse to http://localhost:8080/swagger/index.html. You will see Swagger 2.0 Api documents as shown below:
|
4. Run your app, and browse to http://localhost:8080/swagger/index.html. You will see Swagger 2.0 Api documents as shown below:
|
||||||
|
|
||||||
![swagger_index.html](https://raw.githubusercontent.com/swaggo/swag/master/assets/swagger-image.png)
|
![swagger_index.html](https://raw.githubusercontent.com/swaggo/swag/master/assets/swagger-image.png)
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ generated swagger doc as follows:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Account struct {
|
type Account struct {
|
||||||
ID int `json:"id" extensions:"x-nullable,x-abc=def"` // extensions fields must start with "x-"
|
ID string `json:"id" extensions:"x-nullable,x-abc=def"` // extensions fields must start with "x-"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
141
vendor/github.com/swaggo/swag/cmd/swag/main.go
generated
vendored
141
vendor/github.com/swaggo/swag/cmd/swag/main.go
generated
vendored
|
@ -10,13 +10,77 @@ import (
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
const searchDirFlag = "dir"
|
const (
|
||||||
const generalInfoFlag = "generalInfo"
|
searchDirFlag = "dir"
|
||||||
const propertyStrategyFlag = "propertyStrategy"
|
generalInfoFlag = "generalInfo"
|
||||||
const outputFlag = "output"
|
propertyStrategyFlag = "propertyStrategy"
|
||||||
const parseVendorFlag = "parseVendor"
|
outputFlag = "output"
|
||||||
const parseDependency = "parseDependency"
|
parseVendorFlag = "parseVendor"
|
||||||
const markdownFilesDirFlag = "markdownFiles"
|
parseDependencyFlag = "parseDependency"
|
||||||
|
markdownFilesFlag = "markdownFiles"
|
||||||
|
generatedTimeFlag = "generatedTime"
|
||||||
|
)
|
||||||
|
|
||||||
|
var initFlags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: generalInfoFlag + ", g",
|
||||||
|
Value: "main.go",
|
||||||
|
Usage: "Go file path in which 'swagger general API Info' is written",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: searchDirFlag + ", d",
|
||||||
|
Value: "./",
|
||||||
|
Usage: "Directory you want to parse",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: propertyStrategyFlag + ", p",
|
||||||
|
Value: "camelcase",
|
||||||
|
Usage: "Property Naming Strategy like snakecase,camelcase,pascalcase",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: outputFlag + ", o",
|
||||||
|
Value: "./docs",
|
||||||
|
Usage: "Output directory for all the generated files(swagger.json, swagger.yaml and doc.go)",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: parseVendorFlag,
|
||||||
|
Usage: "Parse go files in 'vendor' folder, disabled by default",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: parseDependencyFlag,
|
||||||
|
Usage: "Parse go files in outside dependency folder, disabled by default",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: markdownFilesFlag + ", md",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Parse folder containing markdown files to use as description, disabled by default",
|
||||||
|
},
|
||||||
|
cli.BoolTFlag{
|
||||||
|
Name: "generatedTime",
|
||||||
|
Usage: "Generate timestamp at the top of docs.go, true by default",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func initAction(c *cli.Context) error {
|
||||||
|
strategy := c.String(propertyStrategyFlag)
|
||||||
|
|
||||||
|
switch strategy {
|
||||||
|
case swag.CamelCase, swag.SnakeCase, swag.PascalCase:
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("not supported %s propertyStrategy", strategy)
|
||||||
|
}
|
||||||
|
|
||||||
|
return gen.New().Build(&gen.Config{
|
||||||
|
SearchDir: c.String(searchDirFlag),
|
||||||
|
MainAPIFile: c.String(generalInfoFlag),
|
||||||
|
PropNamingStrategy: strategy,
|
||||||
|
OutputDir: c.String(outputFlag),
|
||||||
|
ParseVendor: c.Bool(parseVendorFlag),
|
||||||
|
ParseDependency: c.Bool(parseDependencyFlag),
|
||||||
|
MarkdownFilesDir: c.String(markdownFilesFlag),
|
||||||
|
GeneratedTime: c.BoolT(generatedTimeFlag),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
|
@ -27,69 +91,10 @@ func main() {
|
||||||
Name: "init",
|
Name: "init",
|
||||||
Aliases: []string{"i"},
|
Aliases: []string{"i"},
|
||||||
Usage: "Create docs.go",
|
Usage: "Create docs.go",
|
||||||
Action: func(c *cli.Context) error {
|
Action: initAction,
|
||||||
searchDir := c.String(searchDirFlag)
|
Flags: initFlags,
|
||||||
mainAPIFile := c.String(generalInfoFlag)
|
|
||||||
strategy := c.String(propertyStrategyFlag)
|
|
||||||
outputDir := c.String(outputFlag)
|
|
||||||
parseVendor := c.Bool(parseVendorFlag)
|
|
||||||
parseDependency := c.Bool(parseDependency)
|
|
||||||
markdownFilesDir := c.String(markdownFilesDirFlag)
|
|
||||||
|
|
||||||
switch strategy {
|
|
||||||
case swag.CamelCase, swag.SnakeCase, swag.PascalCase:
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("not supported %s propertyStrategy", strategy)
|
|
||||||
}
|
|
||||||
|
|
||||||
return gen.New().Build(&gen.Config{
|
|
||||||
SearchDir: searchDir,
|
|
||||||
MainAPIFile: mainAPIFile,
|
|
||||||
PropNamingStrategy: strategy,
|
|
||||||
OutputDir: outputDir,
|
|
||||||
ParseVendor: parseVendor,
|
|
||||||
ParseDependency: parseDependency,
|
|
||||||
MarkdownFilesDir: markdownFilesDir,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "generalInfo, g",
|
|
||||||
Value: "main.go",
|
|
||||||
Usage: "Go file path in which 'swagger general API Info' is written",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "dir, d",
|
|
||||||
Value: "./",
|
|
||||||
Usage: "Directory you want to parse",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "propertyStrategy, p",
|
|
||||||
Value: "camelcase",
|
|
||||||
Usage: "Property Naming Strategy like snakecase,camelcase,pascalcase",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "output, o",
|
|
||||||
Value: "./docs",
|
|
||||||
Usage: "Output directory for al the generated files(swagger.json, swagger.yaml and doc.go)",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "parseVendor",
|
|
||||||
Usage: "Parse go files in 'vendor' folder, disabled by default",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "parseDependency",
|
|
||||||
Usage: "Parse go files in outside dependency folder, disabled by default",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "markdownFiles, md",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Parse folder containing markdown files to use as description, disabled by default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
109
vendor/github.com/swaggo/swag/gen/gen.go
generated
vendored
109
vendor/github.com/swaggo/swag/gen/gen.go
generated
vendored
|
@ -20,11 +20,19 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Gen presents a generate tool for swag.
|
// Gen presents a generate tool for swag.
|
||||||
type Gen struct{}
|
type Gen struct {
|
||||||
|
jsonIndent func(data interface{}) ([]byte, error)
|
||||||
|
jsonToYAML func(data []byte) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new Gen.
|
// New creates a new Gen.
|
||||||
func New() *Gen {
|
func New() *Gen {
|
||||||
return &Gen{}
|
return &Gen{
|
||||||
|
jsonIndent: func(data interface{}) ([]byte, error) {
|
||||||
|
return json.MarshalIndent(data, "", " ")
|
||||||
|
},
|
||||||
|
jsonToYAML: yaml.JSONToYAML,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config presents Gen configurations.
|
// Config presents Gen configurations.
|
||||||
|
@ -32,7 +40,7 @@ type Config struct {
|
||||||
// SearchDir the swag would be parse
|
// SearchDir the swag would be parse
|
||||||
SearchDir string
|
SearchDir string
|
||||||
|
|
||||||
// OutputDir represents the output directory for al the generated files
|
// OutputDir represents the output directory for all the generated files
|
||||||
OutputDir string
|
OutputDir string
|
||||||
|
|
||||||
// MainAPIFile the Go file path in which 'swagger general API Info' is written
|
// MainAPIFile the Go file path in which 'swagger general API Info' is written
|
||||||
|
@ -49,6 +57,9 @@ type Config struct {
|
||||||
|
|
||||||
// MarkdownFilesDir used to find markdownfiles, which can be used for tag descriptions
|
// MarkdownFilesDir used to find markdownfiles, which can be used for tag descriptions
|
||||||
MarkdownFilesDir string
|
MarkdownFilesDir string
|
||||||
|
|
||||||
|
// GeneratedTime whether swag should generate the timestamp at the top of docs.go
|
||||||
|
GeneratedTime bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds swagger json file for given searchDir and mainAPIFile. Returns json
|
// Build builds swagger json file for given searchDir and mainAPIFile. Returns json
|
||||||
|
@ -77,52 +88,53 @@ func (g *Gen) Build(config *Config) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
docs, err := os.Create(path.Join(config.OutputDir, "docs.go"))
|
docFileName := path.Join(config.OutputDir, "docs.go")
|
||||||
|
jsonFileName := path.Join(config.OutputDir, "swagger.json")
|
||||||
|
yamlFileName := path.Join(config.OutputDir, "swagger.yaml")
|
||||||
|
|
||||||
|
docs, err := os.Create(docFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer docs.Close()
|
defer docs.Close()
|
||||||
|
|
||||||
swaggerJSON, err := os.Create(path.Join(config.OutputDir, "swagger.json"))
|
err = g.writeFile(b, jsonFileName)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer swaggerJSON.Close()
|
|
||||||
|
|
||||||
if _, err := swaggerJSON.Write(b); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
swaggerYAML, err := os.Create(path.Join(config.OutputDir, "swagger.yaml"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer swaggerYAML.Close()
|
y, err := g.jsonToYAML(b)
|
||||||
y, err := yaml.JSONToYAML(b)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot covert json to yaml error: %s", err)
|
return fmt.Errorf("cannot covert json to yaml error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := swaggerYAML.Write(y); err != nil {
|
err = g.writeFile(y, yamlFileName)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write doc
|
|
||||||
err = g.writeGoDoc(docs, swagger)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("create docs.go at %+v", docs.Name())
|
// Write doc
|
||||||
log.Printf("create swagger.json at %+v", swaggerJSON.Name())
|
err = g.writeGoDoc(docs, swagger, config)
|
||||||
log.Printf("create swagger.yaml at %+v", swaggerYAML.Name())
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("create docs.go at %+v", docFileName)
|
||||||
|
log.Printf("create swagger.json at %+v", jsonFileName)
|
||||||
|
log.Printf("create swagger.yaml at %+v", yamlFileName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gen) jsonIndent(data interface{}) ([]byte, error) {
|
func (g *Gen) writeFile(b []byte, file string) error {
|
||||||
return json.MarshalIndent(data, "", " ")
|
f, err := os.Create(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.Write(b)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gen) formatSource(src []byte) []byte {
|
func (g *Gen) formatSource(src []byte) []byte {
|
||||||
|
@ -133,7 +145,7 @@ func (g *Gen) formatSource(src []byte) []byte {
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
|
func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger, config *Config) error {
|
||||||
|
|
||||||
generator, err := template.New("swagger_info").Funcs(template.FuncMap{
|
generator, err := template.New("swagger_info").Funcs(template.FuncMap{
|
||||||
"printDoc": func(v string) string {
|
"printDoc": func(v string) string {
|
||||||
|
@ -186,23 +198,25 @@ func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
|
||||||
|
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
err = generator.Execute(buffer, struct {
|
err = generator.Execute(buffer, struct {
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
Doc string
|
GeneratedTime bool
|
||||||
Host string
|
Doc string
|
||||||
BasePath string
|
Host string
|
||||||
Schemes []string
|
BasePath string
|
||||||
Title string
|
Schemes []string
|
||||||
Description string
|
Title string
|
||||||
Version string
|
Description string
|
||||||
|
Version string
|
||||||
}{
|
}{
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
Doc: string(buf),
|
GeneratedTime: config.GeneratedTime,
|
||||||
Host: swagger.Host,
|
Doc: string(buf),
|
||||||
BasePath: swagger.BasePath,
|
Host: swagger.Host,
|
||||||
Schemes: swagger.Schemes,
|
BasePath: swagger.BasePath,
|
||||||
Title: swagger.Info.Title,
|
Schemes: swagger.Schemes,
|
||||||
Description: swagger.Info.Description,
|
Title: swagger.Info.Title,
|
||||||
Version: swagger.Info.Version,
|
Description: swagger.Info.Description,
|
||||||
|
Version: swagger.Info.Version,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -213,12 +227,11 @@ func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
|
||||||
// write
|
// write
|
||||||
_, err = output.Write(code)
|
_, err = output.Write(code)
|
||||||
return err
|
return err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var packageTemplate = `// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
var packageTemplate = `// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
// This file was generated by swaggo/swag at
|
// This file was generated by swaggo/swag{{ if .GeneratedTime }} at
|
||||||
// {{ .Timestamp }}
|
// {{ .Timestamp }}{{ end }}
|
||||||
|
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
|
|
14
vendor/github.com/swaggo/swag/go.mod
generated
vendored
14
vendor/github.com/swaggo/swag/go.mod
generated
vendored
|
@ -4,11 +4,15 @@ require (
|
||||||
github.com/KyleBanks/depth v1.2.1
|
github.com/KyleBanks/depth v1.2.1
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||||
github.com/ghodss/yaml v1.0.0
|
github.com/ghodss/yaml v1.0.0
|
||||||
github.com/go-openapi/jsonreference v0.19.0
|
github.com/gin-gonic/gin v1.4.0
|
||||||
github.com/go-openapi/spec v0.19.0
|
github.com/go-openapi/jsonreference v0.19.3
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/go-openapi/spec v0.19.4
|
||||||
|
github.com/satori/go.uuid v1.2.0
|
||||||
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
|
||||||
github.com/swaggo/gin-swagger v1.2.0
|
github.com/swaggo/gin-swagger v1.2.0
|
||||||
github.com/urfave/cli v1.20.0
|
github.com/urfave/cli v1.22.2
|
||||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
60
vendor/github.com/swaggo/swag/go.sum
generated
vendored
60
vendor/github.com/swaggo/swag/go.sum
generated
vendored
|
@ -1,74 +1,127 @@
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/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.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/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
|
||||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||||
|
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
|
||||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
||||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||||
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
|
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
|
||||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
|
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
|
||||||
|
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||||
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
|
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
|
||||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||||
|
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
|
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||||
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||||
|
github.com/swaggo/gin-swagger v1.2.0 h1:YskZXEiv51fjOMTsXrOetAjrMDfFaXD79PEoQBOe2W0=
|
||||||
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
||||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
|
github.com/ugorji/go v1.1.5-pre h1:jyJKFOSEbdOc2HODrf2qcCkYOdq7zzXqA9bhW5oV4fM=
|
||||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/ugorji/go/codec v1.1.5-pre h1:5YV9PsFAN+ndcCtTM7s60no7nY7eTG3LPtxhSwuxzCs=
|
||||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
||||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
|
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||||
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/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-20181220203305-927f97764cc3/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-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-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY=
|
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY=
|
||||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/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-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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4=
|
||||||
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
|
||||||
|
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
@ -76,9 +129,14 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b h1:/mJ+GKieZA6hFDQGdWZrjj4AXPl5ylY+5HusG80roy0=
|
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b h1:/mJ+GKieZA6hFDQGdWZrjj4AXPl5ylY+5HusG80roy0=
|
||||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88=
|
||||||
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
|
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
|
112
vendor/github.com/swaggo/swag/operation.go
generated
vendored
112
vendor/github.com/swaggo/swag/operation.go
generated
vendored
|
@ -144,6 +144,7 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
|
||||||
if strings.HasPrefix(refType, "[]") == true {
|
if strings.HasPrefix(refType, "[]") == true {
|
||||||
objectType = "array"
|
objectType = "array"
|
||||||
refType = strings.TrimPrefix(refType, "[]")
|
refType = strings.TrimPrefix(refType, "[]")
|
||||||
|
refType = TransToValidSchemeType(refType)
|
||||||
} else if IsPrimitiveType(refType) ||
|
} else if IsPrimitiveType(refType) ||
|
||||||
paramType == "formData" && refType == "file" {
|
paramType == "formData" && refType == "file" {
|
||||||
objectType = "primitive"
|
objectType = "primitive"
|
||||||
|
@ -174,32 +175,96 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case "object":
|
case "object":
|
||||||
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
|
refType, typeSpec, err := operation.registerSchemaType(refType, astFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
structType, ok := typeSpec.Type.(*ast.StructType)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
|
||||||
|
}
|
||||||
|
refSplit := strings.Split(refType, ".")
|
||||||
|
schema, err := operation.parser.parseStruct(refSplit[0], structType.Fields)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(schema.Properties) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
find := func(arr []string, target string) bool {
|
||||||
|
for _, str := range arr {
|
||||||
|
if str == target {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for name, prop := range schema.Properties {
|
||||||
|
if len(prop.Type) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if prop.Type[0] == "array" &&
|
||||||
|
prop.Items.Schema != nil &&
|
||||||
|
len(prop.Items.Schema.Type) > 0 &&
|
||||||
|
IsSimplePrimitiveType(prop.Items.Schema.Type[0]) {
|
||||||
|
param = createParameter(paramType, prop.Description, name, prop.Type[0], find(schema.Required, name))
|
||||||
|
param.SimpleSchema.Type = prop.Type[0]
|
||||||
|
param.SimpleSchema.Items = &spec.Items{
|
||||||
|
SimpleSchema: spec.SimpleSchema{
|
||||||
|
Type: prop.Items.Schema.Type[0],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else if IsSimplePrimitiveType(prop.Type[0]) {
|
||||||
|
param = createParameter(paramType, prop.Description, name, prop.Type[0], find(schema.Required, name))
|
||||||
|
} else {
|
||||||
|
Println(fmt.Sprintf("skip field [%s] in %s is not supported type for %s", name, refType, paramType))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
param.CommonValidations.Maximum = prop.Maximum
|
||||||
|
param.CommonValidations.Minimum = prop.Minimum
|
||||||
|
param.CommonValidations.ExclusiveMaximum = prop.ExclusiveMaximum
|
||||||
|
param.CommonValidations.ExclusiveMinimum = prop.ExclusiveMinimum
|
||||||
|
param.CommonValidations.MaxLength = prop.MaxLength
|
||||||
|
param.CommonValidations.MinLength = prop.MinLength
|
||||||
|
param.CommonValidations.Pattern = prop.Pattern
|
||||||
|
param.CommonValidations.MaxItems = prop.MaxItems
|
||||||
|
param.CommonValidations.MinItems = prop.MinItems
|
||||||
|
param.CommonValidations.UniqueItems = prop.UniqueItems
|
||||||
|
param.CommonValidations.MultipleOf = prop.MultipleOf
|
||||||
|
param.CommonValidations.Enum = prop.Enum
|
||||||
|
operation.Operation.Parameters = append(operation.Operation.Parameters, param)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
case "body":
|
case "body":
|
||||||
switch objectType {
|
switch objectType {
|
||||||
case "primitive":
|
case "primitive":
|
||||||
param.Schema.Type = spec.StringOrArray{refType}
|
param.Schema.Type = spec.StringOrArray{refType}
|
||||||
case "array":
|
case "array":
|
||||||
|
param.Schema.Type = spec.StringOrArray{objectType}
|
||||||
param.Schema.Items = &spec.SchemaOrArray{
|
param.Schema.Items = &spec.SchemaOrArray{
|
||||||
Schema: &spec.Schema{
|
Schema: &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{},
|
SchemaProps: spec.SchemaProps{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// Arrau of Primitive or Object
|
// Array of Primitive or Object
|
||||||
if IsPrimitiveType(refType) {
|
if IsPrimitiveType(refType) {
|
||||||
param.Schema.Items.Schema.Type = spec.StringOrArray{refType}
|
param.Schema.Items.Schema.Type = spec.StringOrArray{refType}
|
||||||
} else {
|
} else {
|
||||||
if err := operation.registerSchemaType(refType, astFile); err != nil {
|
var err error
|
||||||
|
refType, _, err = operation.registerSchemaType(refType, astFile)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
param.Schema.Items.Schema.Ref = spec.Ref{Ref: jsonreference.MustCreateRef("#/definitions/" + refType)}
|
param.Schema.Items.Schema.Ref = spec.Ref{Ref: jsonreference.MustCreateRef("#/definitions/" + refType)}
|
||||||
}
|
}
|
||||||
case "object":
|
case "object":
|
||||||
if err := operation.registerSchemaType(refType, astFile); err != nil {
|
var err error
|
||||||
|
refType, _, err = operation.registerSchemaType(refType, astFile)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
param.Schema.Type = spec.StringOrArray{objectType}
|
param.Schema.Type = []string{}
|
||||||
param.Schema.Ref = spec.Ref{
|
param.Schema.Ref = spec.Ref{
|
||||||
Ref: jsonreference.MustCreateRef("#/definitions/" + refType),
|
Ref: jsonreference.MustCreateRef("#/definitions/" + refType),
|
||||||
}
|
}
|
||||||
|
@ -215,20 +280,23 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.File) error {
|
func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.File) (string, *ast.TypeSpec, error) {
|
||||||
refSplit := strings.Split(schemaType, ".")
|
if !strings.ContainsRune(schemaType, '.') {
|
||||||
if len(refSplit) != 2 {
|
if astFile == nil {
|
||||||
return nil
|
return schemaType, nil, fmt.Errorf("no package name for type %s", schemaType)
|
||||||
|
}
|
||||||
|
schemaType = astFile.Name.String() + "." + schemaType
|
||||||
}
|
}
|
||||||
|
refSplit := strings.Split(schemaType, ".")
|
||||||
pkgName := refSplit[0]
|
pkgName := refSplit[0]
|
||||||
typeName := refSplit[1]
|
typeName := refSplit[1]
|
||||||
if typeSpec, ok := operation.parser.TypeDefinitions[pkgName][typeName]; ok {
|
if typeSpec, ok := operation.parser.TypeDefinitions[pkgName][typeName]; ok {
|
||||||
operation.parser.registerTypes[schemaType] = typeSpec
|
operation.parser.registerTypes[schemaType] = typeSpec
|
||||||
return nil
|
return schemaType, typeSpec, nil
|
||||||
}
|
}
|
||||||
var typeSpec *ast.TypeSpec
|
var typeSpec *ast.TypeSpec
|
||||||
if astFile == nil {
|
if astFile == nil {
|
||||||
return fmt.Errorf("can not register schema type: %q reason: astFile == nil", schemaType)
|
return schemaType, nil, fmt.Errorf("can not register schema type: %q reason: astFile == nil", schemaType)
|
||||||
}
|
}
|
||||||
for _, imp := range astFile.Imports {
|
for _, imp := range astFile.Imports {
|
||||||
if imp.Name != nil && imp.Name.Name == pkgName { // the import had an alias that matched
|
if imp.Name != nil && imp.Name.Name == pkgName { // the import had an alias that matched
|
||||||
|
@ -239,14 +307,14 @@ func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.F
|
||||||
var err error
|
var err error
|
||||||
typeSpec, err = findTypeDef(impPath, typeName)
|
typeSpec, err = findTypeDef(impPath, typeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can not find type def: %q error: %s", schemaType, err)
|
return schemaType, nil, fmt.Errorf("can not find type def: %q error: %s", schemaType, err)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if typeSpec == nil {
|
if typeSpec == nil {
|
||||||
return fmt.Errorf("can not find schema type: %q", schemaType)
|
return schemaType, nil, fmt.Errorf("can not find schema type: %q", schemaType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := operation.parser.TypeDefinitions[pkgName]; !ok {
|
if _, ok := operation.parser.TypeDefinitions[pkgName]; !ok {
|
||||||
|
@ -255,7 +323,7 @@ func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.F
|
||||||
|
|
||||||
operation.parser.TypeDefinitions[pkgName][typeName] = typeSpec
|
operation.parser.TypeDefinitions[pkgName][typeName] = typeSpec
|
||||||
operation.parser.registerTypes[schemaType] = typeSpec
|
operation.parser.registerTypes[schemaType] = typeSpec
|
||||||
return nil
|
return schemaType, typeSpec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var regexAttributes = map[string]*regexp.Regexp{
|
var regexAttributes = map[string]*regexp.Regexp{
|
||||||
|
@ -437,7 +505,7 @@ func parseMimeTypeList(mimeTypeList string, typeList *[]string, format string) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var routerPattern = regexp.MustCompile(`([\w\.\/\-{}\+]+)[^\[]+\[([^\]]+)`)
|
var routerPattern = regexp.MustCompile(`^(/[\w\.\/\-{}\+:]*)[[:blank:]]+\[(\w+)]`)
|
||||||
|
|
||||||
// ParseRouterComment parses comment for gived `router` comment string.
|
// ParseRouterComment parses comment for gived `router` comment string.
|
||||||
func (operation *Operation) ParseRouterComment(commentLine string) error {
|
func (operation *Operation) ParseRouterComment(commentLine string) error {
|
||||||
|
@ -563,14 +631,12 @@ func (operation *Operation) ParseResponseComment(commentLine string, astFile *as
|
||||||
schemaType := strings.Trim(matches[2], "{}")
|
schemaType := strings.Trim(matches[2], "{}")
|
||||||
refType := matches[3]
|
refType := matches[3]
|
||||||
|
|
||||||
if !IsGolangPrimitiveType(refType) && !strings.Contains(refType, ".") {
|
if !IsGolangPrimitiveType(refType) {
|
||||||
currentPkgName := astFile.Name.String()
|
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
|
||||||
refType = currentPkgName + "." + refType
|
var err error
|
||||||
}
|
if refType, _, err = operation.registerSchemaType(refType, astFile); err != nil {
|
||||||
|
return err
|
||||||
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
|
}
|
||||||
if err := operation.registerSchemaType(refType, astFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
308
vendor/github.com/swaggo/swag/parser.go
generated
vendored
308
vendor/github.com/swaggo/swag/parser.go
generated
vendored
|
@ -46,6 +46,9 @@ type Parser struct {
|
||||||
// TypeDefinitions is a map that stores [package name][type name][*ast.TypeSpec]
|
// TypeDefinitions is a map that stores [package name][type name][*ast.TypeSpec]
|
||||||
TypeDefinitions map[string]map[string]*ast.TypeSpec
|
TypeDefinitions map[string]map[string]*ast.TypeSpec
|
||||||
|
|
||||||
|
// ImportAliases is map that stores [import name][import package name][*ast.ImportSpec]
|
||||||
|
ImportAliases map[string]map[string]*ast.ImportSpec
|
||||||
|
|
||||||
// CustomPrimitiveTypes is a map that stores custom primitive types to actual golang types [type name][string]
|
// CustomPrimitiveTypes is a map that stores custom primitive types to actual golang types [type name][string]
|
||||||
CustomPrimitiveTypes map[string]string
|
CustomPrimitiveTypes map[string]string
|
||||||
|
|
||||||
|
@ -85,6 +88,7 @@ func New(options ...func(*Parser)) *Parser {
|
||||||
},
|
},
|
||||||
files: make(map[string]*ast.File),
|
files: make(map[string]*ast.File),
|
||||||
TypeDefinitions: make(map[string]map[string]*ast.TypeSpec),
|
TypeDefinitions: make(map[string]map[string]*ast.TypeSpec),
|
||||||
|
ImportAliases: make(map[string]map[string]*ast.ImportSpec),
|
||||||
CustomPrimitiveTypes: make(map[string]string),
|
CustomPrimitiveTypes: make(map[string]string),
|
||||||
registerTypes: make(map[string]*ast.TypeSpec),
|
registerTypes: make(map[string]*ast.TypeSpec),
|
||||||
}
|
}
|
||||||
|
@ -521,6 +525,23 @@ func (parser *Parser) ParseType(astFile *ast.File) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, importSpec := range astFile.Imports {
|
||||||
|
if importSpec.Name == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
alias := importSpec.Name.Name
|
||||||
|
|
||||||
|
if _, ok := parser.ImportAliases[alias]; !ok {
|
||||||
|
parser.ImportAliases[alias] = make(map[string]*ast.ImportSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
importParts := strings.Split(strings.Trim(importSpec.Path.Value, "\""), "/")
|
||||||
|
importPkgName := importParts[len(importParts)-1]
|
||||||
|
|
||||||
|
parser.ImportAliases[alias][importPkgName] = importSpec
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parser *Parser) isInStructStack(refTypeName string) bool {
|
func (parser *Parser) isInStructStack(refTypeName string) bool {
|
||||||
|
@ -581,7 +602,7 @@ func (parser *Parser) ParseDefinition(pkgName, typeName string, typeSpec *ast.Ty
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parser.swagger.Definitions[refTypeName] = schema
|
parser.swagger.Definitions[refTypeName] = *schema
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,9 +626,7 @@ func (parser *Parser) collectRequiredFields(pkgName string, properties map[strin
|
||||||
tspec := parser.TypeDefinitions[pkgName][tname]
|
tspec := parser.TypeDefinitions[pkgName][tname]
|
||||||
parser.ParseDefinition(pkgName, tname, tspec)
|
parser.ParseDefinition(pkgName, tname, tspec)
|
||||||
}
|
}
|
||||||
if tname != "object" {
|
requiredFields = append(requiredFields, prop.SchemaProps.Required...)
|
||||||
requiredFields = append(requiredFields, prop.SchemaProps.Required...)
|
|
||||||
}
|
|
||||||
properties[k] = prop
|
properties[k] = prop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,28 +648,40 @@ func fullTypeName(pkgName, typeName string) string {
|
||||||
|
|
||||||
// parseTypeExpr parses given type expression that corresponds to the type under
|
// parseTypeExpr parses given type expression that corresponds to the type under
|
||||||
// given name and package, and returns swagger schema for it.
|
// given name and package, and returns swagger schema for it.
|
||||||
func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr) (spec.Schema, error) {
|
func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr) (*spec.Schema, error) {
|
||||||
//TODO: return pointer to spec.Schema
|
|
||||||
|
|
||||||
switch expr := typeExpr.(type) {
|
switch expr := typeExpr.(type) {
|
||||||
// type Foo struct {...}
|
// type Foo struct {...}
|
||||||
case *ast.StructType:
|
case *ast.StructType:
|
||||||
refTypeName := fullTypeName(pkgName, typeName)
|
refTypeName := fullTypeName(pkgName, typeName)
|
||||||
if schema, isParsed := parser.swagger.Definitions[refTypeName]; isParsed {
|
if schema, isParsed := parser.swagger.Definitions[refTypeName]; isParsed {
|
||||||
return schema, nil
|
return &schema, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser.parseStruct(pkgName, expr.Fields)
|
return parser.parseStruct(pkgName, expr.Fields)
|
||||||
|
|
||||||
// type Foo Baz
|
// type Foo Baz
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
|
if IsGolangPrimitiveType(expr.Name) {
|
||||||
|
return &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: spec.StringOrArray{TransToValidSchemeType(expr.Name)},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
refTypeName := fullTypeName(pkgName, expr.Name)
|
refTypeName := fullTypeName(pkgName, expr.Name)
|
||||||
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
|
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
|
||||||
if typedef, ok := parser.TypeDefinitions[pkgName][expr.Name]; ok {
|
if typedef, ok := parser.TypeDefinitions[pkgName][expr.Name]; ok {
|
||||||
parser.ParseDefinition(pkgName, expr.Name, typedef)
|
parser.ParseDefinition(pkgName, expr.Name, typedef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parser.swagger.Definitions[refTypeName], nil
|
return &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Ref: spec.Ref{
|
||||||
|
Ref: jsonreference.MustCreateRef("#/definitions/" + refTypeName),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
|
||||||
// type Foo *Baz
|
// type Foo *Baz
|
||||||
case *ast.StarExpr:
|
case *ast.StarExpr:
|
||||||
|
@ -660,13 +691,13 @@ func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr)
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
itemSchema, err := parser.parseTypeExpr(pkgName, "", expr.Elt)
|
itemSchema, err := parser.parseTypeExpr(pkgName, "", expr.Elt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return spec.Schema{}, err
|
return &spec.Schema{}, err
|
||||||
}
|
}
|
||||||
return spec.Schema{
|
return &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{"array"},
|
Type: []string{"array"},
|
||||||
Items: &spec.SchemaOrArray{
|
Items: &spec.SchemaOrArray{
|
||||||
Schema: &itemSchema,
|
Schema: itemSchema,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -674,28 +705,25 @@ func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr)
|
||||||
// type Foo pkg.Bar
|
// type Foo pkg.Bar
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
if xIdent, ok := expr.X.(*ast.Ident); ok {
|
if xIdent, ok := expr.X.(*ast.Ident); ok {
|
||||||
pkgName = xIdent.Name
|
return parser.parseTypeExpr(xIdent.Name, expr.Sel.Name, expr.Sel)
|
||||||
typeName = expr.Sel.Name
|
|
||||||
refTypeName := fullTypeName(pkgName, typeName)
|
|
||||||
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
|
|
||||||
typedef := parser.TypeDefinitions[pkgName][typeName]
|
|
||||||
parser.ParseDefinition(pkgName, typeName, typedef)
|
|
||||||
}
|
|
||||||
return parser.swagger.Definitions[refTypeName], nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type Foo map[string]Bar
|
// type Foo map[string]Bar
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
itemSchema, err := parser.parseTypeExpr(pkgName, "", expr.Value)
|
var valueSchema spec.SchemaOrBool
|
||||||
if err != nil {
|
if _, ok := expr.Value.(*ast.InterfaceType); ok {
|
||||||
return spec.Schema{}, err
|
valueSchema.Allows = true
|
||||||
|
} else {
|
||||||
|
schema, err := parser.parseTypeExpr(pkgName, "", expr.Value)
|
||||||
|
if err != nil {
|
||||||
|
return &spec.Schema{}, err
|
||||||
|
}
|
||||||
|
valueSchema.Schema = schema
|
||||||
}
|
}
|
||||||
return spec.Schema{
|
return &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{"object"},
|
Type: []string{"object"},
|
||||||
AdditionalProperties: &spec.SchemaOrBool{
|
AdditionalProperties: &valueSchema,
|
||||||
Schema: &itemSchema,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
// ...
|
// ...
|
||||||
|
@ -703,21 +731,21 @@ func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr)
|
||||||
Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
|
Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec.Schema{
|
return &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{"object"},
|
Type: []string{"object"},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (spec.Schema, error) {
|
func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (*spec.Schema, error) {
|
||||||
|
|
||||||
extraRequired := make([]string, 0)
|
extraRequired := make([]string, 0)
|
||||||
properties := make(map[string]spec.Schema)
|
properties := make(map[string]spec.Schema)
|
||||||
for _, field := range fields.List {
|
for _, field := range fields.List {
|
||||||
fieldProps, requiredFromAnon, err := parser.parseStructField(pkgName, field)
|
fieldProps, requiredFromAnon, err := parser.parseStructField(pkgName, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return spec.Schema{}, err
|
return &spec.Schema{}, err
|
||||||
}
|
}
|
||||||
extraRequired = append(extraRequired, requiredFromAnon...)
|
extraRequired = append(extraRequired, requiredFromAnon...)
|
||||||
for k, v := range fieldProps {
|
for k, v := range fieldProps {
|
||||||
|
@ -730,14 +758,11 @@ func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (spec.S
|
||||||
|
|
||||||
// unset required from properties because we've collected them
|
// unset required from properties because we've collected them
|
||||||
for k, prop := range properties {
|
for k, prop := range properties {
|
||||||
tname := prop.SchemaProps.Type[0]
|
prop.SchemaProps.Required = make([]string, 0)
|
||||||
if tname != "object" {
|
|
||||||
prop.SchemaProps.Required = make([]string, 0)
|
|
||||||
}
|
|
||||||
properties[k] = prop
|
properties[k] = prop
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec.Schema{
|
return &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{"object"},
|
Type: []string{"object"},
|
||||||
Properties: properties,
|
Properties: properties,
|
||||||
|
@ -747,6 +772,7 @@ func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (spec.S
|
||||||
|
|
||||||
type structField struct {
|
type structField struct {
|
||||||
name string
|
name string
|
||||||
|
desc string
|
||||||
schemaType string
|
schemaType string
|
||||||
arrayType string
|
arrayType string
|
||||||
formatType string
|
formatType string
|
||||||
|
@ -763,6 +789,34 @@ type structField struct {
|
||||||
extensions map[string]interface{}
|
extensions map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sf *structField) toStandardSchema() *spec.Schema {
|
||||||
|
required := make([]string, 0)
|
||||||
|
if sf.isRequired {
|
||||||
|
required = append(required, sf.name)
|
||||||
|
}
|
||||||
|
return &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{sf.schemaType},
|
||||||
|
Description: sf.desc,
|
||||||
|
Format: sf.formatType,
|
||||||
|
Required: required,
|
||||||
|
Maximum: sf.maximum,
|
||||||
|
Minimum: sf.minimum,
|
||||||
|
MaxLength: sf.maxLength,
|
||||||
|
MinLength: sf.minLength,
|
||||||
|
Enum: sf.enums,
|
||||||
|
Default: sf.defaultValue,
|
||||||
|
},
|
||||||
|
SwaggerSchemaProps: spec.SwaggerSchemaProps{
|
||||||
|
Example: sf.exampleValue,
|
||||||
|
ReadOnly: sf.readOnly,
|
||||||
|
},
|
||||||
|
VendorExtensible: spec.VendorExtensible{
|
||||||
|
Extensions: sf.extensions,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[string]spec.Schema, []string, error) {
|
func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[string]spec.Schema, []string, error) {
|
||||||
properties := map[string]spec.Schema{}
|
properties := map[string]spec.Schema{}
|
||||||
|
|
||||||
|
@ -796,7 +850,7 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
properties[k] = v
|
properties[k] = v
|
||||||
}
|
}
|
||||||
case "array":
|
case "array":
|
||||||
properties[typeName] = schema
|
properties[typeName] = *schema
|
||||||
default:
|
default:
|
||||||
Printf("Can't extract properties from a schema of type '%s'", schemaType)
|
Printf("Can't extract properties from a schema of type '%s'", schemaType)
|
||||||
}
|
}
|
||||||
|
@ -808,30 +862,51 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
|
|
||||||
structField, err := parser.parseField(field)
|
structField, err := parser.parseField(field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return properties, nil, nil
|
return properties, nil, err
|
||||||
}
|
}
|
||||||
if structField.name == "" {
|
if structField.name == "" {
|
||||||
return properties, nil, nil
|
return properties, nil, nil
|
||||||
}
|
}
|
||||||
var desc string
|
|
||||||
if field.Doc != nil {
|
|
||||||
desc = strings.TrimSpace(field.Doc.Text())
|
|
||||||
}
|
|
||||||
if desc == "" && field.Comment != nil {
|
|
||||||
desc = strings.TrimSpace(field.Comment.Text())
|
|
||||||
}
|
|
||||||
// TODO: find package of schemaType and/or arrayType
|
// TODO: find package of schemaType and/or arrayType
|
||||||
if structField.crossPkg != "" {
|
if structField.crossPkg != "" {
|
||||||
pkgName = structField.crossPkg
|
pkgName = structField.crossPkg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fillObject := func(src, dest interface{}) error {
|
||||||
|
bin, err := json.Marshal(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(bin, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
//for spec.Schema have implemented json.Marshaler, here in another way to convert
|
||||||
|
fillSchema := func(src, dest *spec.Schema) error {
|
||||||
|
err = fillObject(&src.SchemaProps, &dest.SchemaProps)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = fillObject(&src.SwaggerSchemaProps, &dest.SwaggerSchemaProps)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fillObject(&src.VendorExtensible, &dest.VendorExtensible)
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := parser.TypeDefinitions[pkgName][structField.schemaType]; ok { // user type field
|
if _, ok := parser.TypeDefinitions[pkgName][structField.schemaType]; ok { // user type field
|
||||||
// write definition if not yet present
|
// write definition if not yet present
|
||||||
parser.ParseDefinition(pkgName, structField.schemaType,
|
parser.ParseDefinition(pkgName, structField.schemaType,
|
||||||
parser.TypeDefinitions[pkgName][structField.schemaType])
|
parser.TypeDefinitions[pkgName][structField.schemaType])
|
||||||
|
required := make([]string, 0)
|
||||||
|
if structField.isRequired {
|
||||||
|
required = append(required, structField.name)
|
||||||
|
}
|
||||||
properties[structField.name] = spec.Schema{
|
properties[structField.name] = spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{"object"}, // to avoid swagger validation error
|
Type: []string{"object"}, // to avoid swagger validation error
|
||||||
Description: desc,
|
Description: structField.desc,
|
||||||
|
Required: required,
|
||||||
Ref: spec.Ref{
|
Ref: spec.Ref{
|
||||||
Ref: jsonreference.MustCreateRef("#/definitions/" + pkgName + "." + structField.schemaType),
|
Ref: jsonreference.MustCreateRef("#/definitions/" + pkgName + "." + structField.schemaType),
|
||||||
},
|
},
|
||||||
|
@ -845,10 +920,15 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
if _, ok := parser.TypeDefinitions[pkgName][structField.arrayType]; ok { // user type in array
|
if _, ok := parser.TypeDefinitions[pkgName][structField.arrayType]; ok { // user type in array
|
||||||
parser.ParseDefinition(pkgName, structField.arrayType,
|
parser.ParseDefinition(pkgName, structField.arrayType,
|
||||||
parser.TypeDefinitions[pkgName][structField.arrayType])
|
parser.TypeDefinitions[pkgName][structField.arrayType])
|
||||||
|
required := make([]string, 0)
|
||||||
|
if structField.isRequired {
|
||||||
|
required = append(required, structField.name)
|
||||||
|
}
|
||||||
properties[structField.name] = spec.Schema{
|
properties[structField.name] = spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{structField.schemaType},
|
Type: []string{structField.schemaType},
|
||||||
Description: desc,
|
Description: structField.desc,
|
||||||
|
Required: required,
|
||||||
Items: &spec.SchemaOrArray{
|
Items: &spec.SchemaOrArray{
|
||||||
Schema: &spec.Schema{
|
Schema: &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
|
@ -881,7 +961,7 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
properties[structField.name] = spec.Schema{
|
properties[structField.name] = spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{structField.schemaType},
|
Type: []string{structField.schemaType},
|
||||||
Description: desc,
|
Description: structField.desc,
|
||||||
Items: &spec.SchemaOrArray{
|
Items: &spec.SchemaOrArray{
|
||||||
Schema: &spec.Schema{
|
Schema: &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
|
@ -895,6 +975,36 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
ReadOnly: structField.readOnly,
|
ReadOnly: structField.readOnly,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
schema, _ := parser.parseTypeExpr(pkgName, "", astTypeArray.Elt)
|
||||||
|
properties[structField.name] = spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{structField.schemaType},
|
||||||
|
Description: structField.desc,
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: schema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SwaggerSchemaProps: spec.SwaggerSchemaProps{
|
||||||
|
ReadOnly: structField.readOnly,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if structField.arrayType == "array" {
|
||||||
|
if astTypeArray, ok := field.Type.(*ast.ArrayType); ok {
|
||||||
|
schema, _ := parser.parseTypeExpr(pkgName, "", astTypeArray.Elt)
|
||||||
|
properties[structField.name] = spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{structField.schemaType},
|
||||||
|
Description: structField.desc,
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: schema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SwaggerSchemaProps: spec.SwaggerSchemaProps{
|
||||||
|
ReadOnly: structField.readOnly,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -907,7 +1017,7 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
properties[structField.name] = spec.Schema{
|
properties[structField.name] = spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Type: []string{structField.schemaType},
|
Type: []string{structField.schemaType},
|
||||||
Description: desc,
|
Description: structField.desc,
|
||||||
Format: structField.formatType,
|
Format: structField.formatType,
|
||||||
Required: required,
|
Required: required,
|
||||||
Items: &spec.SchemaOrArray{
|
Items: &spec.SchemaOrArray{
|
||||||
|
@ -930,47 +1040,36 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if astTypeMap, ok := field.Type.(*ast.MapType); ok { // if map
|
||||||
|
stdSchema := structField.toStandardSchema()
|
||||||
|
mapValueSchema, err := parser.parseTypeExpr(pkgName, "", astTypeMap)
|
||||||
|
if err != nil {
|
||||||
|
return properties, nil, err
|
||||||
|
}
|
||||||
|
stdSchema.Type = mapValueSchema.Type
|
||||||
|
stdSchema.AdditionalProperties = mapValueSchema.AdditionalProperties
|
||||||
|
properties[structField.name] = *stdSchema
|
||||||
} else {
|
} else {
|
||||||
required := make([]string, 0)
|
stdSchema := structField.toStandardSchema()
|
||||||
if structField.isRequired {
|
properties[structField.name] = *stdSchema
|
||||||
required = append(required, structField.name)
|
|
||||||
}
|
|
||||||
properties[structField.name] = spec.Schema{
|
|
||||||
SchemaProps: spec.SchemaProps{
|
|
||||||
Type: []string{structField.schemaType},
|
|
||||||
Description: desc,
|
|
||||||
Format: structField.formatType,
|
|
||||||
Required: required,
|
|
||||||
Maximum: structField.maximum,
|
|
||||||
Minimum: structField.minimum,
|
|
||||||
MaxLength: structField.maxLength,
|
|
||||||
MinLength: structField.minLength,
|
|
||||||
Enum: structField.enums,
|
|
||||||
Default: structField.defaultValue,
|
|
||||||
},
|
|
||||||
SwaggerSchemaProps: spec.SwaggerSchemaProps{
|
|
||||||
Example: structField.exampleValue,
|
|
||||||
ReadOnly: structField.readOnly,
|
|
||||||
},
|
|
||||||
VendorExtensible: spec.VendorExtensible{
|
|
||||||
Extensions: structField.extensions,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if nestStruct, ok := field.Type.(*ast.StarExpr); ok {
|
if nestStar, ok := field.Type.(*ast.StarExpr); ok {
|
||||||
schema, err := parser.parseTypeExpr(pkgName, structField.schemaType, nestStruct.X)
|
if !IsGolangPrimitiveType(structField.schemaType) {
|
||||||
if err != nil {
|
schema, err := parser.parseTypeExpr(pkgName, structField.schemaType, nestStar.X)
|
||||||
return nil, nil, err
|
if err != nil {
|
||||||
|
return properties, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(schema.SchemaProps.Type) > 0 {
|
||||||
|
err = fillSchema(schema, stdSchema)
|
||||||
|
if err != nil {
|
||||||
|
return properties, nil, err
|
||||||
|
}
|
||||||
|
properties[structField.name] = *stdSchema
|
||||||
|
return properties, nil, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if nestStruct, ok := field.Type.(*ast.StructType); ok {
|
||||||
if len(schema.SchemaProps.Type) > 0 {
|
|
||||||
properties[structField.name] = schema
|
|
||||||
return properties, nil, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nestStruct, ok := field.Type.(*ast.StructType)
|
|
||||||
if ok {
|
|
||||||
props := map[string]spec.Schema{}
|
props := map[string]spec.Schema{}
|
||||||
nestRequired := make([]string, 0)
|
nestRequired := make([]string, 0)
|
||||||
for _, v := range nestStruct.Fields.List {
|
for _, v := range nestStruct.Fields.List {
|
||||||
|
@ -986,26 +1085,9 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
|
||||||
props[k] = v
|
props[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stdSchema.Properties = props
|
||||||
properties[structField.name] = spec.Schema{
|
stdSchema.Required = nestRequired
|
||||||
SchemaProps: spec.SchemaProps{
|
properties[structField.name] = *stdSchema
|
||||||
Type: []string{structField.schemaType},
|
|
||||||
Description: desc,
|
|
||||||
Format: structField.formatType,
|
|
||||||
Properties: props,
|
|
||||||
Required: nestRequired,
|
|
||||||
Maximum: structField.maximum,
|
|
||||||
Minimum: structField.minimum,
|
|
||||||
MaxLength: structField.maxLength,
|
|
||||||
MinLength: structField.minLength,
|
|
||||||
Enum: structField.enums,
|
|
||||||
Default: structField.defaultValue,
|
|
||||||
},
|
|
||||||
SwaggerSchemaProps: spec.SwaggerSchemaProps{
|
|
||||||
Example: structField.exampleValue,
|
|
||||||
ReadOnly: structField.readOnly,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return properties, nil, nil
|
return properties, nil, nil
|
||||||
|
@ -1069,6 +1151,13 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
|
||||||
structField.name = toLowerCamelCase(structField.name)
|
structField.name = toLowerCamelCase(structField.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if field.Doc != nil {
|
||||||
|
structField.desc = strings.TrimSpace(field.Doc.Text())
|
||||||
|
}
|
||||||
|
if structField.desc == "" && field.Comment != nil {
|
||||||
|
structField.desc = strings.TrimSpace(field.Comment.Text())
|
||||||
|
}
|
||||||
|
|
||||||
if field.Tag == nil {
|
if field.Tag == nil {
|
||||||
return structField, nil
|
return structField, nil
|
||||||
}
|
}
|
||||||
|
@ -1098,6 +1187,9 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
|
||||||
if len(parts) >= 2 {
|
if len(parts) >= 2 {
|
||||||
if newSchemaType == "array" {
|
if newSchemaType == "array" {
|
||||||
newArrayType = parts[1]
|
newArrayType = parts[1]
|
||||||
|
if err := CheckSchemaType(newArrayType); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
} else if newSchemaType == "primitive" {
|
} else if newSchemaType == "primitive" {
|
||||||
newSchemaType = parts[1]
|
newSchemaType = parts[1]
|
||||||
newArrayType = parts[1]
|
newArrayType = parts[1]
|
||||||
|
@ -1107,9 +1199,7 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
|
||||||
if err := CheckSchemaType(newSchemaType); err != nil {
|
if err := CheckSchemaType(newSchemaType); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := CheckSchemaType(newArrayType); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
structField.schemaType = newSchemaType
|
structField.schemaType = newSchemaType
|
||||||
structField.arrayType = newArrayType
|
structField.arrayType = newArrayType
|
||||||
}
|
}
|
||||||
|
|
53
vendor/github.com/swaggo/swag/property.go
generated
vendored
53
vendor/github.com/swaggo/swag/property.go
generated
vendored
|
@ -60,6 +60,19 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
|
||||||
parser.ParseDefinition(pkgName.Name, astTypeSelectorExpr.Sel.Name, typeDefinitions)
|
parser.ParseDefinition(pkgName.Name, astTypeSelectorExpr.Sel.Name, typeDefinitions)
|
||||||
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, pkgName.Name)
|
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, pkgName.Name)
|
||||||
}
|
}
|
||||||
|
if aliasedNames, ok := parser.ImportAliases[pkgName.Name]; ok {
|
||||||
|
for aliasedName := range aliasedNames {
|
||||||
|
if typeDefinitions, ok := parser.TypeDefinitions[aliasedName][astTypeSelectorExpr.Sel.Name]; ok {
|
||||||
|
if expr, ok := typeDefinitions.Type.(*ast.SelectorExpr); ok {
|
||||||
|
if primitiveType, err := convertFromSpecificToPrimitive(expr.Sel.Name); err == nil {
|
||||||
|
return propertyNewFunc(primitiveType, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parser.ParseDefinition(aliasedName, astTypeSelectorExpr.Sel.Name, typeDefinitions)
|
||||||
|
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, aliasedName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[astTypeSelectorExpr.Sel.Name]; isCustomType {
|
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[astTypeSelectorExpr.Sel.Name]; isCustomType {
|
||||||
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
|
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
|
||||||
}
|
}
|
||||||
|
@ -91,10 +104,7 @@ func getPropertyName(expr ast.Expr, parser *Parser) (propertyName, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if astTypeArray, ok := expr.(*ast.ArrayType); ok { // if array
|
if astTypeArray, ok := expr.(*ast.ArrayType); ok { // if array
|
||||||
if _, ok := astTypeArray.Elt.(*ast.StructType); ok {
|
return getArrayPropertyName(astTypeArray.Elt, parser), nil
|
||||||
return propertyName{SchemaType: "array", ArrayType: "object"}, nil
|
|
||||||
}
|
|
||||||
return getArrayPropertyName(astTypeArray, parser), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := expr.(*ast.MapType); ok { // if map
|
if _, ok := expr.(*ast.MapType); ok { // if map
|
||||||
|
@ -111,22 +121,27 @@ func getPropertyName(expr ast.Expr, parser *Parser) (propertyName, error) {
|
||||||
return propertyName{}, errors.New("not supported" + fmt.Sprint(expr))
|
return propertyName{}, errors.New("not supported" + fmt.Sprint(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArrayPropertyName(astTypeArray *ast.ArrayType, parser *Parser) propertyName {
|
func getArrayPropertyName(astTypeArrayElt ast.Expr, parser *Parser) propertyName {
|
||||||
if astTypeArrayExpr, ok := astTypeArray.Elt.(*ast.SelectorExpr); ok {
|
switch elt := astTypeArrayElt.(type) {
|
||||||
return parseFieldSelectorExpr(astTypeArrayExpr, parser, newArrayProperty)
|
case *ast.StructType, *ast.MapType, *ast.InterfaceType:
|
||||||
}
|
return propertyName{SchemaType: "array", ArrayType: "object"}
|
||||||
if astTypeArrayExpr, ok := astTypeArray.Elt.(*ast.StarExpr); ok {
|
case *ast.ArrayType:
|
||||||
if astTypeArraySel, ok := astTypeArrayExpr.X.(*ast.SelectorExpr); ok {
|
return propertyName{SchemaType: "array", ArrayType: "array"}
|
||||||
return parseFieldSelectorExpr(astTypeArraySel, parser, newArrayProperty)
|
case *ast.StarExpr:
|
||||||
|
return getArrayPropertyName(elt.X, parser)
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
return parseFieldSelectorExpr(elt, parser, newArrayProperty)
|
||||||
|
case *ast.Ident:
|
||||||
|
name := TransToValidSchemeType(elt.Name)
|
||||||
|
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[name]; isCustomType {
|
||||||
|
name = actualPrimitiveType
|
||||||
}
|
}
|
||||||
if astTypeArrayIdent, ok := astTypeArrayExpr.X.(*ast.Ident); ok {
|
return propertyName{SchemaType: "array", ArrayType: name}
|
||||||
name := TransToValidSchemeType(astTypeArrayIdent.Name)
|
default:
|
||||||
return propertyName{SchemaType: "array", ArrayType: name}
|
name := TransToValidSchemeType(fmt.Sprintf("%s", astTypeArrayElt))
|
||||||
|
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[name]; isCustomType {
|
||||||
|
name = actualPrimitiveType
|
||||||
}
|
}
|
||||||
|
return propertyName{SchemaType: "array", ArrayType: name}
|
||||||
}
|
}
|
||||||
itemTypeName := TransToValidSchemeType(fmt.Sprintf("%s", astTypeArray.Elt))
|
|
||||||
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[itemTypeName]; isCustomType {
|
|
||||||
itemTypeName = actualPrimitiveType
|
|
||||||
}
|
|
||||||
return propertyName{SchemaType: "array", ArrayType: itemTypeName}
|
|
||||||
}
|
}
|
||||||
|
|
10
vendor/github.com/swaggo/swag/schema.go
generated
vendored
10
vendor/github.com/swaggo/swag/schema.go
generated
vendored
|
@ -10,6 +10,16 @@ func CheckSchemaType(typeName string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSimplePrimitiveType determine whether the type name is a simple primitive type
|
||||||
|
func IsSimplePrimitiveType(typeName string) bool {
|
||||||
|
switch typeName {
|
||||||
|
case "string", "number", "integer", "boolean":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IsPrimitiveType determine whether the type name is a primitive type
|
// IsPrimitiveType determine whether the type name is a primitive type
|
||||||
func IsPrimitiveType(typeName string) bool {
|
func IsPrimitiveType(typeName string) bool {
|
||||||
switch typeName {
|
switch typeName {
|
||||||
|
|
2
vendor/github.com/swaggo/swag/version.go
generated
vendored
2
vendor/github.com/swaggo/swag/version.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
package swag
|
package swag
|
||||||
|
|
||||||
// Version of swag
|
// Version of swag
|
||||||
const Version = "v1.6.3"
|
const Version = "v1.6.5"
|
||||||
|
|
5
vendor/golang.org/x/tools/go/ast/astutil/imports.go
generated
vendored
5
vendor/golang.org/x/tools/go/ast/astutil/imports.go
generated
vendored
|
@ -275,9 +275,10 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
|
||||||
|
|
||||||
// We deleted an entry but now there may be
|
// We deleted an entry but now there may be
|
||||||
// a blank line-sized hole where the import was.
|
// a blank line-sized hole where the import was.
|
||||||
if line-lastLine > 1 {
|
if line-lastLine > 1 || !gen.Rparen.IsValid() {
|
||||||
// There was a blank line immediately preceding the deleted import,
|
// There was a blank line immediately preceding the deleted import,
|
||||||
// so there's no need to close the hole.
|
// so there's no need to close the hole. The right parenthesis is
|
||||||
|
// invalid after AddImport to an import statement without parenthesis.
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else if line != fset.File(gen.Rparen).LineCount() {
|
} else if line != fset.File(gen.Rparen).LineCount() {
|
||||||
// There was no blank line. Close the hole.
|
// There was no blank line. Close the hole.
|
||||||
|
|
4
vendor/golang.org/x/tools/go/ast/inspector/inspector.go
generated
vendored
4
vendor/golang.org/x/tools/go/ast/inspector/inspector.go
generated
vendored
|
@ -90,7 +90,7 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
|
||||||
// The types argument, if non-empty, enables type-based filtering of
|
// The types argument, if non-empty, enables type-based filtering of
|
||||||
// events. The function f if is called only for nodes whose type
|
// events. The function f if is called only for nodes whose type
|
||||||
// matches an element of the types slice.
|
// matches an element of the types slice.
|
||||||
func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (prune bool)) {
|
func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) {
|
||||||
mask := maskOf(types)
|
mask := maskOf(types)
|
||||||
for i := 0; i < len(in.events); {
|
for i := 0; i < len(in.events); {
|
||||||
ev := in.events[i]
|
ev := in.events[i]
|
||||||
|
@ -114,7 +114,7 @@ func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (prun
|
||||||
// supplies each call to f an additional argument, the current
|
// supplies each call to f an additional argument, the current
|
||||||
// traversal stack. The stack's first element is the outermost node,
|
// traversal stack. The stack's first element is the outermost node,
|
||||||
// an *ast.File; its last is the innermost, n.
|
// an *ast.File; its last is the innermost, n.
|
||||||
func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (prune bool)) {
|
func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) {
|
||||||
mask := maskOf(types)
|
mask := maskOf(types)
|
||||||
var stack []ast.Node
|
var stack []ast.Node
|
||||||
for i := 0; i < len(in.events); {
|
for i := 0; i < len(in.events); {
|
||||||
|
|
3
vendor/golang.org/x/tools/go/packages/doc.go
generated
vendored
3
vendor/golang.org/x/tools/go/packages/doc.go
generated
vendored
|
@ -60,8 +60,7 @@ causes Load to run in LoadFiles mode, collecting minimal information.
|
||||||
See the documentation for type Config for details.
|
See the documentation for type Config for details.
|
||||||
|
|
||||||
As noted earlier, the Config.Mode controls the amount of detail
|
As noted earlier, the Config.Mode controls the amount of detail
|
||||||
reported about the loaded packages, with each mode returning all the data of the
|
reported about the loaded packages. See the documentation for type LoadMode
|
||||||
previous mode with some extra added. See the documentation for type LoadMode
|
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
Most tools should pass their command-line arguments (after any flags)
|
Most tools should pass their command-line arguments (after any flags)
|
||||||
|
|
7
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
7
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
|
@ -84,13 +84,14 @@ func findExternalDriver(cfg *Config) driver {
|
||||||
cmd.Stdin = bytes.NewReader(req)
|
cmd.Stdin = bytes.NewReader(req)
|
||||||
cmd.Stdout = buf
|
cmd.Stdout = buf
|
||||||
cmd.Stderr = stderr
|
cmd.Stderr = stderr
|
||||||
if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd, words...), stderr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
|
return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
|
||||||
}
|
}
|
||||||
|
if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd, words...), stderr)
|
||||||
|
}
|
||||||
|
|
||||||
var response driverResponse
|
var response driverResponse
|
||||||
if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
|
if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
637
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
637
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
|
@ -6,17 +6,16 @@ package packages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/types"
|
"go/types"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -24,9 +23,6 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"golang.org/x/tools/go/internal/packagesdriver"
|
"golang.org/x/tools/go/internal/packagesdriver"
|
||||||
"golang.org/x/tools/internal/gopathwalk"
|
|
||||||
"golang.org/x/tools/internal/semver"
|
|
||||||
"golang.org/x/tools/internal/span"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// debug controls verbose logging.
|
// debug controls verbose logging.
|
||||||
|
@ -45,16 +41,21 @@ type responseDeduper struct {
|
||||||
dr *driverResponse
|
dr *driverResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
// init fills in r with a driverResponse.
|
func newDeduper() *responseDeduper {
|
||||||
func (r *responseDeduper) init(dr *driverResponse) {
|
return &responseDeduper{
|
||||||
r.dr = dr
|
dr: &driverResponse{},
|
||||||
r.seenRoots = map[string]bool{}
|
seenRoots: map[string]bool{},
|
||||||
r.seenPackages = map[string]*Package{}
|
seenPackages: map[string]*Package{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// addAll fills in r with a driverResponse.
|
||||||
|
func (r *responseDeduper) addAll(dr *driverResponse) {
|
||||||
for _, pkg := range dr.Packages {
|
for _, pkg := range dr.Packages {
|
||||||
r.seenPackages[pkg.ID] = pkg
|
r.addPackage(pkg)
|
||||||
}
|
}
|
||||||
for _, root := range dr.Roots {
|
for _, root := range dr.Roots {
|
||||||
r.seenRoots[root] = true
|
r.addRoot(root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,25 +75,47 @@ func (r *responseDeduper) addRoot(id string) {
|
||||||
r.dr.Roots = append(r.dr.Roots, id)
|
r.dr.Roots = append(r.dr.Roots, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// goInfo contains global information from the go tool.
|
type golistState struct {
|
||||||
type goInfo struct {
|
cfg *Config
|
||||||
rootDirs map[string]string
|
ctx context.Context
|
||||||
env goEnv
|
|
||||||
|
envOnce sync.Once
|
||||||
|
goEnvError error
|
||||||
|
goEnv map[string]string
|
||||||
|
|
||||||
|
rootsOnce sync.Once
|
||||||
|
rootDirsError error
|
||||||
|
rootDirs map[string]string
|
||||||
|
|
||||||
|
// vendorDirs caches the (non)existence of vendor directories.
|
||||||
|
vendorDirs map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type goEnv struct {
|
// getEnv returns Go environment variables. Only specific variables are
|
||||||
modulesOn bool
|
// populated -- computing all of them is slow.
|
||||||
|
func (state *golistState) getEnv() (map[string]string, error) {
|
||||||
|
state.envOnce.Do(func() {
|
||||||
|
var b *bytes.Buffer
|
||||||
|
b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH")
|
||||||
|
if state.goEnvError != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.goEnv = make(map[string]string)
|
||||||
|
decoder := json.NewDecoder(b)
|
||||||
|
if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return state.goEnv, state.goEnvError
|
||||||
}
|
}
|
||||||
|
|
||||||
func determineEnv(cfg *Config) goEnv {
|
// mustGetEnv is a convenience function that can be used if getEnv has already succeeded.
|
||||||
buf, err := invokeGo(cfg, "env", "GOMOD")
|
func (state *golistState) mustGetEnv() map[string]string {
|
||||||
|
env, err := state.getEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return goEnv{}
|
panic(fmt.Sprintf("mustGetEnv: %v", err))
|
||||||
}
|
}
|
||||||
gomod := bytes.TrimSpace(buf.Bytes())
|
|
||||||
|
|
||||||
env := goEnv{}
|
|
||||||
env.modulesOn = len(gomod) > 0
|
|
||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,47 +123,38 @@ func determineEnv(cfg *Config) goEnv {
|
||||||
// the build system package structure.
|
// the build system package structure.
|
||||||
// See driver for more details.
|
// See driver for more details.
|
||||||
func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
||||||
var sizes types.Sizes
|
// Make sure that any asynchronous go commands are killed when we return.
|
||||||
|
parentCtx := cfg.Context
|
||||||
|
if parentCtx == nil {
|
||||||
|
parentCtx = context.Background()
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithCancel(parentCtx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
response := newDeduper()
|
||||||
|
|
||||||
|
// Fill in response.Sizes asynchronously if necessary.
|
||||||
var sizeserr error
|
var sizeserr error
|
||||||
var sizeswg sync.WaitGroup
|
var sizeswg sync.WaitGroup
|
||||||
if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
|
if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
|
||||||
sizeswg.Add(1)
|
sizeswg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
sizes, sizeserr = getSizes(cfg)
|
var sizes types.Sizes
|
||||||
|
sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.Dir, usesExportData(cfg))
|
||||||
|
// types.SizesFor always returns nil or a *types.StdSizes.
|
||||||
|
response.dr.Sizes, _ = sizes.(*types.StdSizes)
|
||||||
sizeswg.Done()
|
sizeswg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
defer sizeswg.Wait()
|
|
||||||
|
|
||||||
// start fetching rootDirs
|
state := &golistState{
|
||||||
var info goInfo
|
cfg: cfg,
|
||||||
var rootDirsReady, envReady = make(chan struct{}), make(chan struct{})
|
ctx: ctx,
|
||||||
go func() {
|
vendorDirs: map[string]bool{},
|
||||||
info.rootDirs = determineRootDirs(cfg)
|
|
||||||
close(rootDirsReady)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
info.env = determineEnv(cfg)
|
|
||||||
close(envReady)
|
|
||||||
}()
|
|
||||||
getGoInfo := func() *goInfo {
|
|
||||||
<-rootDirsReady
|
|
||||||
<-envReady
|
|
||||||
return &info
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that we don't leak goroutines: Load is synchronous, so callers will
|
|
||||||
// not expect it to access the fields of cfg after the call returns.
|
|
||||||
defer getGoInfo()
|
|
||||||
|
|
||||||
// always pass getGoInfo to golistDriver
|
|
||||||
golistDriver := func(cfg *Config, patterns ...string) (*driverResponse, error) {
|
|
||||||
return golistDriver(cfg, getGoInfo, patterns...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine files requested in contains patterns
|
// Determine files requested in contains patterns
|
||||||
var containFiles []string
|
var containFiles []string
|
||||||
var packagesNamed []string
|
|
||||||
restPatterns := make([]string, 0, len(patterns))
|
restPatterns := make([]string, 0, len(patterns))
|
||||||
// Extract file= and other [querytype]= patterns. Report an error if querytype
|
// Extract file= and other [querytype]= patterns. Report an error if querytype
|
||||||
// doesn't exist.
|
// doesn't exist.
|
||||||
|
@ -156,8 +170,6 @@ extractQueries:
|
||||||
containFiles = append(containFiles, value)
|
containFiles = append(containFiles, value)
|
||||||
case "pattern":
|
case "pattern":
|
||||||
restPatterns = append(restPatterns, value)
|
restPatterns = append(restPatterns, value)
|
||||||
case "iamashamedtousethedisabledqueryname":
|
|
||||||
packagesNamed = append(packagesNamed, value)
|
|
||||||
case "": // not a reserved query
|
case "": // not a reserved query
|
||||||
restPatterns = append(restPatterns, pattern)
|
restPatterns = append(restPatterns, pattern)
|
||||||
default:
|
default:
|
||||||
|
@ -173,52 +185,34 @@ extractQueries:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response := &responseDeduper{}
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// See if we have any patterns to pass through to go list. Zero initial
|
// See if we have any patterns to pass through to go list. Zero initial
|
||||||
// patterns also requires a go list call, since it's the equivalent of
|
// patterns also requires a go list call, since it's the equivalent of
|
||||||
// ".".
|
// ".".
|
||||||
if len(restPatterns) > 0 || len(patterns) == 0 {
|
if len(restPatterns) > 0 || len(patterns) == 0 {
|
||||||
dr, err := golistDriver(cfg, restPatterns...)
|
dr, err := state.createDriverResponse(restPatterns...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response.init(dr)
|
response.addAll(dr)
|
||||||
} else {
|
|
||||||
response.init(&driverResponse{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeswg.Wait()
|
|
||||||
if sizeserr != nil {
|
|
||||||
return nil, sizeserr
|
|
||||||
}
|
|
||||||
// types.SizesFor always returns nil or a *types.StdSizes
|
|
||||||
response.dr.Sizes, _ = sizes.(*types.StdSizes)
|
|
||||||
|
|
||||||
var containsCandidates []string
|
|
||||||
|
|
||||||
if len(containFiles) != 0 {
|
if len(containFiles) != 0 {
|
||||||
if err := runContainsQueries(cfg, golistDriver, response, containFiles, getGoInfo); err != nil {
|
if err := state.runContainsQueries(response, containFiles); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(packagesNamed) != 0 {
|
modifiedPkgs, needPkgs, err := state.processGolistOverlay(response)
|
||||||
if err := runNamedQueries(cfg, golistDriver, response, packagesNamed); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiedPkgs, needPkgs, err := processGolistOverlay(cfg, response, getGoInfo)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var containsCandidates []string
|
||||||
if len(containFiles) > 0 {
|
if len(containFiles) > 0 {
|
||||||
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
||||||
containsCandidates = append(containsCandidates, needPkgs...)
|
containsCandidates = append(containsCandidates, needPkgs...)
|
||||||
}
|
}
|
||||||
if err := addNeededOverlayPackages(cfg, golistDriver, response, needPkgs, getGoInfo); err != nil {
|
if err := state.addNeededOverlayPackages(response, needPkgs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Check candidate packages for containFiles.
|
// Check candidate packages for containFiles.
|
||||||
|
@ -247,33 +241,32 @@ extractQueries:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sizeswg.Wait()
|
||||||
|
if sizeserr != nil {
|
||||||
|
return nil, sizeserr
|
||||||
|
}
|
||||||
return response.dr, nil
|
return response.dr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDeduper, pkgs []string, getGoInfo func() *goInfo) error {
|
func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error {
|
||||||
if len(pkgs) == 0 {
|
if len(pkgs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
drivercfg := *cfg
|
dr, err := state.createDriverResponse(pkgs...)
|
||||||
if getGoInfo().env.modulesOn {
|
|
||||||
drivercfg.BuildFlags = append(drivercfg.BuildFlags, "-mod=readonly")
|
|
||||||
}
|
|
||||||
dr, err := driver(&drivercfg, pkgs...)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, pkg := range dr.Packages {
|
for _, pkg := range dr.Packages {
|
||||||
response.addPackage(pkg)
|
response.addPackage(pkg)
|
||||||
}
|
}
|
||||||
_, needPkgs, err := processGolistOverlay(cfg, response, getGoInfo)
|
_, needPkgs, err := state.processGolistOverlay(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return addNeededOverlayPackages(cfg, driver, response, needPkgs, getGoInfo)
|
return state.addNeededOverlayPackages(response, needPkgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, queries []string, goInfo func() *goInfo) error {
|
func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
|
||||||
for _, query := range queries {
|
for _, query := range queries {
|
||||||
// TODO(matloob): Do only one query per directory.
|
// TODO(matloob): Do only one query per directory.
|
||||||
fdir := filepath.Dir(query)
|
fdir := filepath.Dir(query)
|
||||||
|
@ -283,42 +276,16 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
|
return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
|
||||||
}
|
}
|
||||||
dirResponse, err := driver(cfg, pattern)
|
dirResponse, err := state.createDriverResponse(pattern)
|
||||||
if err != nil {
|
|
||||||
|
// If there was an error loading the package, or the package is returned
|
||||||
|
// with errors, try to load the file as an ad-hoc package.
|
||||||
|
// Usually the error will appear in a returned package, but may not if we're
|
||||||
|
// in module mode and the ad-hoc is located outside a module.
|
||||||
|
if err != nil || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 &&
|
||||||
|
len(dirResponse.Packages[0].Errors) == 1 {
|
||||||
var queryErr error
|
var queryErr error
|
||||||
if dirResponse, queryErr = adHocPackage(cfg, driver, pattern, query); queryErr != nil {
|
if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil {
|
||||||
return err // return the original error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// `go list` can report errors for files that are not listed as part of a package's GoFiles.
|
|
||||||
// In the case of an invalid Go file, we should assume that it is part of package if only
|
|
||||||
// one package is in the response. The file may have valid contents in an overlay.
|
|
||||||
if len(dirResponse.Packages) == 1 {
|
|
||||||
pkg := dirResponse.Packages[0]
|
|
||||||
for i, err := range pkg.Errors {
|
|
||||||
s := errorSpan(err)
|
|
||||||
if !s.IsValid() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if len(pkg.CompiledGoFiles) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
dir := filepath.Dir(pkg.CompiledGoFiles[0])
|
|
||||||
filename := filepath.Join(dir, filepath.Base(s.URI().Filename()))
|
|
||||||
if info, err := os.Stat(filename); err != nil || info.IsDir() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if !contains(pkg.CompiledGoFiles, filename) {
|
|
||||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename)
|
|
||||||
pkg.GoFiles = append(pkg.GoFiles, filename)
|
|
||||||
pkg.Errors = append(pkg.Errors[:i], pkg.Errors[i+1:]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// A final attempt to construct an ad-hoc package.
|
|
||||||
if len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].Errors) == 1 {
|
|
||||||
var queryErr error
|
|
||||||
if dirResponse, queryErr = adHocPackage(cfg, driver, pattern, query); queryErr != nil {
|
|
||||||
return err // return the original error
|
return err // return the original error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,345 +314,47 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// adHocPackage attempts to construct an ad-hoc package given a query that failed.
|
// adhocPackage attempts to load or construct an ad-hoc package for a given
|
||||||
func adHocPackage(cfg *Config, driver driver, pattern, query string) (*driverResponse, error) {
|
// query, if the original call to the driver produced inadequate results.
|
||||||
// There was an error loading the package. Try to load the file as an ad-hoc package.
|
func (state *golistState) adhocPackage(pattern, query string) (*driverResponse, error) {
|
||||||
// Usually the error will appear in a returned package, but may not if we're in modules mode
|
response, err := state.createDriverResponse(query)
|
||||||
// and the ad-hoc is located outside a module.
|
|
||||||
dirResponse, err := driver(cfg, query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// If we get nothing back from `go list`, try to make this file into its own ad-hoc package.
|
// If we get nothing back from `go list`,
|
||||||
if len(dirResponse.Packages) == 0 && err == nil {
|
// try to make this file into its own ad-hoc package.
|
||||||
dirResponse.Packages = append(dirResponse.Packages, &Package{
|
// TODO(rstambler): Should this check against the original response?
|
||||||
|
if len(response.Packages) == 0 {
|
||||||
|
response.Packages = append(response.Packages, &Package{
|
||||||
ID: "command-line-arguments",
|
ID: "command-line-arguments",
|
||||||
PkgPath: query,
|
PkgPath: query,
|
||||||
GoFiles: []string{query},
|
GoFiles: []string{query},
|
||||||
CompiledGoFiles: []string{query},
|
CompiledGoFiles: []string{query},
|
||||||
Imports: make(map[string]*Package),
|
Imports: make(map[string]*Package),
|
||||||
})
|
})
|
||||||
dirResponse.Roots = append(dirResponse.Roots, "command-line-arguments")
|
response.Roots = append(response.Roots, "command-line-arguments")
|
||||||
}
|
}
|
||||||
// Special case to handle issue #33482:
|
// Handle special cases.
|
||||||
// If this is a file= query for ad-hoc packages where the file only exists on an overlay,
|
if len(response.Packages) == 1 {
|
||||||
// and exists outside of a module, add the file in for the package.
|
// golang/go#33482: If this is a file= query for ad-hoc packages where
|
||||||
if len(dirResponse.Packages) == 1 && (dirResponse.Packages[0].ID == "command-line-arguments" ||
|
// the file only exists on an overlay, and exists outside of a module,
|
||||||
filepath.ToSlash(dirResponse.Packages[0].PkgPath) == filepath.ToSlash(query)) {
|
// add the file to the package and remove the errors.
|
||||||
if len(dirResponse.Packages[0].GoFiles) == 0 {
|
if response.Packages[0].ID == "command-line-arguments" ||
|
||||||
filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath
|
filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) {
|
||||||
// TODO(matloob): check if the file is outside of a root dir?
|
if len(response.Packages[0].GoFiles) == 0 {
|
||||||
for path := range cfg.Overlay {
|
filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath
|
||||||
if path == filename {
|
// TODO(matloob): check if the file is outside of a root dir?
|
||||||
dirResponse.Packages[0].Errors = nil
|
for path := range state.cfg.Overlay {
|
||||||
dirResponse.Packages[0].GoFiles = []string{path}
|
if path == filename {
|
||||||
dirResponse.Packages[0].CompiledGoFiles = []string{path}
|
response.Packages[0].Errors = nil
|
||||||
|
response.Packages[0].GoFiles = []string{path}
|
||||||
|
response.Packages[0].CompiledGoFiles = []string{path}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dirResponse, nil
|
return response, nil
|
||||||
}
|
|
||||||
|
|
||||||
func contains(files []string, filename string) bool {
|
|
||||||
for _, f := range files {
|
|
||||||
if f == filename {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// errorSpan attempts to parse a standard `go list` error message
|
|
||||||
// by stripping off the trailing error message.
|
|
||||||
//
|
|
||||||
// It works only on errors whose message is prefixed by colon,
|
|
||||||
// followed by a space (": "). For example:
|
|
||||||
//
|
|
||||||
// attributes.go:13:1: expected 'package', found 'type'
|
|
||||||
//
|
|
||||||
func errorSpan(err Error) span.Span {
|
|
||||||
if err.Pos == "" {
|
|
||||||
input := strings.TrimSpace(err.Msg)
|
|
||||||
msgIndex := strings.Index(input, ": ")
|
|
||||||
if msgIndex < 0 {
|
|
||||||
return span.Parse(input)
|
|
||||||
}
|
|
||||||
return span.Parse(input[:msgIndex])
|
|
||||||
}
|
|
||||||
return span.Parse(err.Pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
// modCacheRegexp splits a path in a module cache into module, module version, and package.
|
|
||||||
var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`)
|
|
||||||
|
|
||||||
func runNamedQueries(cfg *Config, driver driver, response *responseDeduper, queries []string) error {
|
|
||||||
// calling `go env` isn't free; bail out if there's nothing to do.
|
|
||||||
if len(queries) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Determine which directories are relevant to scan.
|
|
||||||
roots, modRoot, err := roots(cfg)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan the selected directories. Simple matches, from GOPATH/GOROOT
|
|
||||||
// or the local module, can simply be "go list"ed. Matches from the
|
|
||||||
// module cache need special treatment.
|
|
||||||
var matchesMu sync.Mutex
|
|
||||||
var simpleMatches, modCacheMatches []string
|
|
||||||
add := func(root gopathwalk.Root, dir string) {
|
|
||||||
// Walk calls this concurrently; protect the result slices.
|
|
||||||
matchesMu.Lock()
|
|
||||||
defer matchesMu.Unlock()
|
|
||||||
|
|
||||||
path := dir
|
|
||||||
if dir != root.Path {
|
|
||||||
path = dir[len(root.Path)+1:]
|
|
||||||
}
|
|
||||||
if pathMatchesQueries(path, queries) {
|
|
||||||
switch root.Type {
|
|
||||||
case gopathwalk.RootModuleCache:
|
|
||||||
modCacheMatches = append(modCacheMatches, path)
|
|
||||||
case gopathwalk.RootCurrentModule:
|
|
||||||
// We'd need to read go.mod to find the full
|
|
||||||
// import path. Relative's easier.
|
|
||||||
rel, err := filepath.Rel(cfg.Dir, dir)
|
|
||||||
if err != nil {
|
|
||||||
// This ought to be impossible, since
|
|
||||||
// we found dir in the current module.
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
simpleMatches = append(simpleMatches, "./"+rel)
|
|
||||||
case gopathwalk.RootGOPATH, gopathwalk.RootGOROOT:
|
|
||||||
simpleMatches = append(simpleMatches, path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startWalk := time.Now()
|
|
||||||
gopathwalk.Walk(roots, add, gopathwalk.Options{ModulesEnabled: modRoot != "", Debug: debug})
|
|
||||||
cfg.Logf("%v for walk", time.Since(startWalk))
|
|
||||||
|
|
||||||
// Weird special case: the top-level package in a module will be in
|
|
||||||
// whatever directory the user checked the repository out into. It's
|
|
||||||
// more reasonable for that to not match the package name. So, if there
|
|
||||||
// are any Go files in the mod root, query it just to be safe.
|
|
||||||
if modRoot != "" {
|
|
||||||
rel, err := filepath.Rel(cfg.Dir, modRoot)
|
|
||||||
if err != nil {
|
|
||||||
panic(err) // See above.
|
|
||||||
}
|
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(modRoot)
|
|
||||||
if err != nil {
|
|
||||||
panic(err) // See above.
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range files {
|
|
||||||
if strings.HasSuffix(f.Name(), ".go") {
|
|
||||||
simpleMatches = append(simpleMatches, rel)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addResponse := func(r *driverResponse) {
|
|
||||||
for _, pkg := range r.Packages {
|
|
||||||
response.addPackage(pkg)
|
|
||||||
for _, name := range queries {
|
|
||||||
if pkg.Name == name {
|
|
||||||
response.addRoot(pkg.ID)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(simpleMatches) != 0 {
|
|
||||||
resp, err := driver(cfg, simpleMatches...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
addResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Module cache matches are tricky. We want to avoid downloading new
|
|
||||||
// versions of things, so we need to use the ones present in the cache.
|
|
||||||
// go list doesn't accept version specifiers, so we have to write out a
|
|
||||||
// temporary module, and do the list in that module.
|
|
||||||
if len(modCacheMatches) != 0 {
|
|
||||||
// Collect all the matches, deduplicating by major version
|
|
||||||
// and preferring the newest.
|
|
||||||
type modInfo struct {
|
|
||||||
mod string
|
|
||||||
major string
|
|
||||||
}
|
|
||||||
mods := make(map[modInfo]string)
|
|
||||||
var imports []string
|
|
||||||
for _, modPath := range modCacheMatches {
|
|
||||||
matches := modCacheRegexp.FindStringSubmatch(modPath)
|
|
||||||
mod, ver := filepath.ToSlash(matches[1]), matches[2]
|
|
||||||
importPath := filepath.ToSlash(filepath.Join(matches[1], matches[3]))
|
|
||||||
|
|
||||||
major := semver.Major(ver)
|
|
||||||
if prevVer, ok := mods[modInfo{mod, major}]; !ok || semver.Compare(ver, prevVer) > 0 {
|
|
||||||
mods[modInfo{mod, major}] = ver
|
|
||||||
}
|
|
||||||
|
|
||||||
imports = append(imports, importPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the temporary module.
|
|
||||||
var gomod bytes.Buffer
|
|
||||||
gomod.WriteString("module modquery\nrequire (\n")
|
|
||||||
for mod, version := range mods {
|
|
||||||
gomod.WriteString("\t" + mod.mod + " " + version + "\n")
|
|
||||||
}
|
|
||||||
gomod.WriteString(")\n")
|
|
||||||
|
|
||||||
tmpCfg := *cfg
|
|
||||||
|
|
||||||
// We're only trying to look at stuff in the module cache, so
|
|
||||||
// disable the network. This should speed things up, and has
|
|
||||||
// prevented errors in at least one case, #28518.
|
|
||||||
tmpCfg.Env = append([]string{"GOPROXY=off"}, cfg.Env...)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
tmpCfg.Dir, err = ioutil.TempDir("", "gopackages-modquery")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpCfg.Dir)
|
|
||||||
|
|
||||||
if err := ioutil.WriteFile(filepath.Join(tmpCfg.Dir, "go.mod"), gomod.Bytes(), 0777); err != nil {
|
|
||||||
return fmt.Errorf("writing go.mod for module cache query: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the query, using the import paths calculated from the matches above.
|
|
||||||
resp, err := driver(&tmpCfg, imports...)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("querying module cache matches: %v", err)
|
|
||||||
}
|
|
||||||
addResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSizes(cfg *Config) (types.Sizes, error) {
|
|
||||||
return packagesdriver.GetSizesGolist(cfg.Context, cfg.BuildFlags, cfg.Env, cfg.Dir, usesExportData(cfg))
|
|
||||||
}
|
|
||||||
|
|
||||||
// roots selects the appropriate paths to walk based on the passed-in configuration,
|
|
||||||
// particularly the environment and the presence of a go.mod in cfg.Dir's parents.
|
|
||||||
func roots(cfg *Config) ([]gopathwalk.Root, string, error) {
|
|
||||||
stdout, err := invokeGo(cfg, "env", "GOROOT", "GOPATH", "GOMOD")
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
fields := strings.Split(stdout.String(), "\n")
|
|
||||||
if len(fields) != 4 || len(fields[3]) != 0 {
|
|
||||||
return nil, "", fmt.Errorf("go env returned unexpected output: %q", stdout.String())
|
|
||||||
}
|
|
||||||
goroot, gopath, gomod := fields[0], filepath.SplitList(fields[1]), fields[2]
|
|
||||||
var modDir string
|
|
||||||
if gomod != "" {
|
|
||||||
modDir = filepath.Dir(gomod)
|
|
||||||
}
|
|
||||||
|
|
||||||
var roots []gopathwalk.Root
|
|
||||||
// Always add GOROOT.
|
|
||||||
roots = append(roots, gopathwalk.Root{
|
|
||||||
Path: filepath.Join(goroot, "/src"),
|
|
||||||
Type: gopathwalk.RootGOROOT,
|
|
||||||
})
|
|
||||||
// If modules are enabled, scan the module dir.
|
|
||||||
if modDir != "" {
|
|
||||||
roots = append(roots, gopathwalk.Root{
|
|
||||||
Path: modDir,
|
|
||||||
Type: gopathwalk.RootCurrentModule,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// Add either GOPATH/src or GOPATH/pkg/mod, depending on module mode.
|
|
||||||
for _, p := range gopath {
|
|
||||||
if modDir != "" {
|
|
||||||
roots = append(roots, gopathwalk.Root{
|
|
||||||
Path: filepath.Join(p, "/pkg/mod"),
|
|
||||||
Type: gopathwalk.RootModuleCache,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
roots = append(roots, gopathwalk.Root{
|
|
||||||
Path: filepath.Join(p, "/src"),
|
|
||||||
Type: gopathwalk.RootGOPATH,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return roots, modDir, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// These functions were copied from goimports. See further documentation there.
|
|
||||||
|
|
||||||
// pathMatchesQueries is adapted from pkgIsCandidate.
|
|
||||||
// TODO: is it reasonable to do Contains here, rather than an exact match on a path component?
|
|
||||||
func pathMatchesQueries(path string, queries []string) bool {
|
|
||||||
lastTwo := lastTwoComponents(path)
|
|
||||||
for _, query := range queries {
|
|
||||||
if strings.Contains(lastTwo, query) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if hasHyphenOrUpperASCII(lastTwo) && !hasHyphenOrUpperASCII(query) {
|
|
||||||
lastTwo = lowerASCIIAndRemoveHyphen(lastTwo)
|
|
||||||
if strings.Contains(lastTwo, query) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// lastTwoComponents returns at most the last two path components
|
|
||||||
// of v, using either / or \ as the path separator.
|
|
||||||
func lastTwoComponents(v string) string {
|
|
||||||
nslash := 0
|
|
||||||
for i := len(v) - 1; i >= 0; i-- {
|
|
||||||
if v[i] == '/' || v[i] == '\\' {
|
|
||||||
nslash++
|
|
||||||
if nslash == 2 {
|
|
||||||
return v[i:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasHyphenOrUpperASCII(s string) bool {
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
b := s[i]
|
|
||||||
if b == '-' || ('A' <= b && b <= 'Z') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func lowerASCIIAndRemoveHyphen(s string) (ret string) {
|
|
||||||
buf := make([]byte, 0, len(s))
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
b := s[i]
|
|
||||||
switch {
|
|
||||||
case b == '-':
|
|
||||||
continue
|
|
||||||
case 'A' <= b && b <= 'Z':
|
|
||||||
buf = append(buf, b+('a'-'A'))
|
|
||||||
default:
|
|
||||||
buf = append(buf, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string(buf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields must match go list;
|
// Fields must match go list;
|
||||||
|
@ -730,10 +399,9 @@ func otherFiles(p *jsonPackage) [][]string {
|
||||||
return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
|
return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
|
||||||
}
|
}
|
||||||
|
|
||||||
// golistDriver uses the "go list" command to expand the pattern
|
// createDriverResponse uses the "go list" command to expand the pattern
|
||||||
// words and return metadata for the specified packages. dir may be
|
// words and return a response for the specified packages.
|
||||||
// "" and env may be nil, as per os/exec.Command.
|
func (state *golistState) createDriverResponse(words ...string) (*driverResponse, error) {
|
||||||
func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driverResponse, error) {
|
|
||||||
// go list uses the following identifiers in ImportPath and Imports:
|
// go list uses the following identifiers in ImportPath and Imports:
|
||||||
//
|
//
|
||||||
// "p" -- importable package or main (command)
|
// "p" -- importable package or main (command)
|
||||||
|
@ -747,7 +415,7 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv
|
||||||
|
|
||||||
// Run "go list" for complete
|
// Run "go list" for complete
|
||||||
// information on the specified packages.
|
// information on the specified packages.
|
||||||
buf, err := invokeGo(cfg, golistargs(cfg, words)...)
|
buf, err := state.invokeGo("list", golistargs(state.cfg, words)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -782,7 +450,10 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv
|
||||||
// contained in a known module or GOPATH entry. This will allow the package to be
|
// contained in a known module or GOPATH entry. This will allow the package to be
|
||||||
// properly "reclaimed" when overlays are processed.
|
// properly "reclaimed" when overlays are processed.
|
||||||
if filepath.IsAbs(p.ImportPath) && p.Error != nil {
|
if filepath.IsAbs(p.ImportPath) && p.Error != nil {
|
||||||
pkgPath, ok := getPkgPath(cfg, p.ImportPath, rootsDirs)
|
pkgPath, ok, err := state.getPkgPath(p.ImportPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if ok {
|
if ok {
|
||||||
p.ImportPath = pkgPath
|
p.ImportPath = pkgPath
|
||||||
}
|
}
|
||||||
|
@ -803,6 +474,7 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv
|
||||||
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
|
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
|
||||||
CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
|
CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
|
||||||
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
|
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
|
||||||
|
forTest: p.ForTest,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Work around https://golang.org/issue/28749:
|
// Work around https://golang.org/issue/28749:
|
||||||
|
@ -879,9 +551,15 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Error != nil {
|
if p.Error != nil {
|
||||||
|
msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363.
|
||||||
|
// Address golang.org/issue/35964 by appending import stack to error message.
|
||||||
|
if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 {
|
||||||
|
msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack)
|
||||||
|
}
|
||||||
pkg.Errors = append(pkg.Errors, Error{
|
pkg.Errors = append(pkg.Errors, Error{
|
||||||
Pos: p.Error.Pos,
|
Pos: p.Error.Pos,
|
||||||
Msg: strings.TrimSpace(p.Error.Err), // Trim to work around golang.org/issue/32363.
|
Msg: msg,
|
||||||
|
Kind: ListError,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,22 +570,20 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPkgPath finds the package path of a directory if it's relative to a root directory.
|
// getPkgPath finds the package path of a directory if it's relative to a root directory.
|
||||||
func getPkgPath(cfg *Config, dir string, goInfo func() *goInfo) (string, bool) {
|
func (state *golistState) getPkgPath(dir string) (string, bool, error) {
|
||||||
absDir, err := filepath.Abs(dir)
|
absDir, err := filepath.Abs(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cfg.Logf("error getting absolute path of %s: %v", dir, err)
|
return "", false, err
|
||||||
return "", false
|
|
||||||
}
|
}
|
||||||
for rdir, rpath := range goInfo().rootDirs {
|
roots, err := state.determineRootDirs()
|
||||||
absRdir, err := filepath.Abs(rdir)
|
if err != nil {
|
||||||
if err != nil {
|
return "", false, err
|
||||||
cfg.Logf("error getting absolute path of %s: %v", rdir, err)
|
}
|
||||||
continue
|
|
||||||
}
|
for rdir, rpath := range roots {
|
||||||
// Make sure that the directory is in the module,
|
// Make sure that the directory is in the module,
|
||||||
// to avoid creating a path relative to another module.
|
// to avoid creating a path relative to another module.
|
||||||
if !strings.HasPrefix(absDir, absRdir) {
|
if !strings.HasPrefix(absDir, rdir) {
|
||||||
cfg.Logf("%s does not have prefix %s", absDir, absRdir)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// TODO(matloob): This doesn't properly handle symlinks.
|
// TODO(matloob): This doesn't properly handle symlinks.
|
||||||
|
@ -922,11 +598,11 @@ func getPkgPath(cfg *Config, dir string, goInfo func() *goInfo) (string, bool) {
|
||||||
// Once the file is saved, gopls, or the next invocation of the tool will get the correct
|
// Once the file is saved, gopls, or the next invocation of the tool will get the correct
|
||||||
// result straight from golist.
|
// result straight from golist.
|
||||||
// TODO(matloob): Implement module tiebreaking?
|
// TODO(matloob): Implement module tiebreaking?
|
||||||
return path.Join(rpath, filepath.ToSlash(r)), true
|
return path.Join(rpath, filepath.ToSlash(r)), true, nil
|
||||||
}
|
}
|
||||||
return filepath.ToSlash(r), true
|
return filepath.ToSlash(r), true, nil
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// absJoin absolutizes and flattens the lists of files.
|
// absJoin absolutizes and flattens the lists of files.
|
||||||
|
@ -945,8 +621,8 @@ func absJoin(dir string, fileses ...[]string) (res []string) {
|
||||||
func golistargs(cfg *Config, words []string) []string {
|
func golistargs(cfg *Config, words []string) []string {
|
||||||
const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
|
const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
|
||||||
fullargs := []string{
|
fullargs := []string{
|
||||||
"list", "-e", "-json",
|
"-e", "-json",
|
||||||
fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypesInfo|NeedTypesSizes) != 0),
|
fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0),
|
||||||
fmt.Sprintf("-test=%t", cfg.Tests),
|
fmt.Sprintf("-test=%t", cfg.Tests),
|
||||||
fmt.Sprintf("-export=%t", usesExportData(cfg)),
|
fmt.Sprintf("-export=%t", usesExportData(cfg)),
|
||||||
fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0),
|
fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0),
|
||||||
|
@ -961,10 +637,17 @@ func golistargs(cfg *Config, words []string) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// invokeGo returns the stdout of a go command invocation.
|
// invokeGo returns the stdout of a go command invocation.
|
||||||
func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) {
|
||||||
|
cfg := state.cfg
|
||||||
|
|
||||||
stdout := new(bytes.Buffer)
|
stdout := new(bytes.Buffer)
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
cmd := exec.CommandContext(cfg.Context, "go", args...)
|
goArgs := []string{verb}
|
||||||
|
if verb != "env" {
|
||||||
|
goArgs = append(goArgs, cfg.BuildFlags...)
|
||||||
|
}
|
||||||
|
goArgs = append(goArgs, args...)
|
||||||
|
cmd := exec.CommandContext(state.ctx, "go", goArgs...)
|
||||||
// On darwin the cwd gets resolved to the real path, which breaks anything that
|
// On darwin the cwd gets resolved to the real path, which breaks anything that
|
||||||
// expects the working directory to keep the original path, including the
|
// expects the working directory to keep the original path, including the
|
||||||
// go command when dealing with modules.
|
// go command when dealing with modules.
|
||||||
|
@ -976,7 +659,7 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
||||||
cmd.Stdout = stdout
|
cmd.Stdout = stdout
|
||||||
cmd.Stderr = stderr
|
cmd.Stderr = stderr
|
||||||
defer func(start time.Time) {
|
defer func(start time.Time) {
|
||||||
cfg.Logf("%s for %v, stderr: <<%s>> stdout: <<%s>>\n", time.Since(start), cmdDebugStr(cmd, args...), stderr, stdout)
|
cfg.Logf("%s for %v, stderr: <<%s>> stdout: <<%s>>\n", time.Since(start), cmdDebugStr(cmd, goArgs...), stderr, stdout)
|
||||||
}(time.Now())
|
}(time.Now())
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
|
|
182
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
182
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
|
@ -1,11 +1,11 @@
|
||||||
package packages
|
package packages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -16,7 +16,7 @@ import (
|
||||||
// sometimes incorrect.
|
// sometimes incorrect.
|
||||||
// TODO(matloob): Handle unsupported cases, including the following:
|
// TODO(matloob): Handle unsupported cases, including the following:
|
||||||
// - determining the correct package to add given a new import path
|
// - determining the correct package to add given a new import path
|
||||||
func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func() *goInfo) (modifiedPkgs, needPkgs []string, err error) {
|
func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
|
||||||
havePkgs := make(map[string]string) // importPath -> non-test package ID
|
havePkgs := make(map[string]string) // importPath -> non-test package ID
|
||||||
needPkgsSet := make(map[string]bool)
|
needPkgsSet := make(map[string]bool)
|
||||||
modifiedPkgsSet := make(map[string]bool)
|
modifiedPkgsSet := make(map[string]bool)
|
||||||
|
@ -34,7 +34,7 @@ func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func(
|
||||||
// potentially modifying the transitive set of dependencies).
|
// potentially modifying the transitive set of dependencies).
|
||||||
var overlayAddsImports bool
|
var overlayAddsImports bool
|
||||||
|
|
||||||
for opath, contents := range cfg.Overlay {
|
for opath, contents := range state.cfg.Overlay {
|
||||||
base := filepath.Base(opath)
|
base := filepath.Base(opath)
|
||||||
dir := filepath.Dir(opath)
|
dir := filepath.Dir(opath)
|
||||||
var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
|
var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
|
||||||
|
@ -86,7 +86,10 @@ func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func(
|
||||||
if pkg == nil {
|
if pkg == nil {
|
||||||
// Try to find the module or gopath dir the file is contained in.
|
// Try to find the module or gopath dir the file is contained in.
|
||||||
// Then for modules, add the module opath to the beginning.
|
// Then for modules, add the module opath to the beginning.
|
||||||
pkgPath, ok := getPkgPath(cfg, dir, rootDirs)
|
pkgPath, ok, err := state.getPkgPath(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -114,6 +117,11 @@ func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func(
|
||||||
if isTestFile && !isXTest && testVariantOf != nil {
|
if isTestFile && !isXTest && testVariantOf != nil {
|
||||||
pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
|
pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
|
||||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
|
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
|
||||||
|
// Add the package under test and its imports to the test variant.
|
||||||
|
pkg.forTest = testVariantOf.PkgPath
|
||||||
|
for k, v := range testVariantOf.Imports {
|
||||||
|
pkg.Imports[k] = &Package{ID: v.ID}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,48 +132,57 @@ func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func(
|
||||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
|
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
|
||||||
modifiedPkgsSet[pkg.ID] = true
|
modifiedPkgsSet[pkg.ID] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear out the package's errors, since we've probably corrected
|
||||||
|
// them by adding the overlay. This may eliminate some legitimate
|
||||||
|
// errors, but that's a risk with overlays in general.
|
||||||
|
pkg.Errors = nil
|
||||||
|
|
||||||
imports, err := extractImports(opath, contents)
|
imports, err := extractImports(opath, contents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Let the parser or type checker report errors later.
|
// Let the parser or type checker report errors later.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, imp := range imports {
|
for _, imp := range imports {
|
||||||
_, found := pkg.Imports[imp]
|
if _, found := pkg.Imports[imp]; found {
|
||||||
if !found {
|
continue
|
||||||
overlayAddsImports = true
|
}
|
||||||
// TODO(matloob): Handle cases when the following block isn't correct.
|
overlayAddsImports = true
|
||||||
// These include imports of vendored packages, etc.
|
id, ok := havePkgs[imp]
|
||||||
id, ok := havePkgs[imp]
|
if !ok {
|
||||||
if !ok {
|
var err error
|
||||||
id = imp
|
id, err = state.resolveImport(dir, imp)
|
||||||
}
|
if err != nil {
|
||||||
pkg.Imports[imp] = &Package{ID: id}
|
return nil, nil, err
|
||||||
// Add dependencies to the non-test variant version of this package as wel.
|
|
||||||
if testVariantOf != nil {
|
|
||||||
testVariantOf.Imports[imp] = &Package{ID: id}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pkg.Imports[imp] = &Package{ID: id}
|
||||||
|
// Add dependencies to the non-test variant version of this package as well.
|
||||||
|
if testVariantOf != nil {
|
||||||
|
testVariantOf.Imports[imp] = &Package{ID: id}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// toPkgPath tries to guess the package path given the id.
|
// toPkgPath guesses the package path given the id.
|
||||||
// This isn't always correct -- it's certainly wrong for
|
toPkgPath := func(sourceDir, id string) (string, error) {
|
||||||
// vendored packages' paths.
|
if i := strings.IndexByte(id, ' '); i >= 0 {
|
||||||
toPkgPath := func(id string) string {
|
return state.resolveImport(sourceDir, id[:i])
|
||||||
// TODO(matloob): Handle vendor paths.
|
|
||||||
i := strings.IndexByte(id, ' ')
|
|
||||||
if i >= 0 {
|
|
||||||
return id[:i]
|
|
||||||
}
|
}
|
||||||
return id
|
return state.resolveImport(sourceDir, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do another pass now that new packages have been created to determine the
|
// Now that new packages have been created, do another pass to determine
|
||||||
// set of missing packages.
|
// the new set of missing packages.
|
||||||
for _, pkg := range response.dr.Packages {
|
for _, pkg := range response.dr.Packages {
|
||||||
for _, imp := range pkg.Imports {
|
for _, imp := range pkg.Imports {
|
||||||
pkgPath := toPkgPath(imp.ID)
|
if len(pkg.GoFiles) == 0 {
|
||||||
|
return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
|
||||||
|
}
|
||||||
|
pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
if _, ok := havePkgs[pkgPath]; !ok {
|
if _, ok := havePkgs[pkgPath]; !ok {
|
||||||
needPkgsSet[pkgPath] = true
|
needPkgsSet[pkgPath] = true
|
||||||
}
|
}
|
||||||
|
@ -185,6 +202,52 @@ func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func(
|
||||||
return modifiedPkgs, needPkgs, err
|
return modifiedPkgs, needPkgs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolveImport finds the the ID of a package given its import path.
|
||||||
|
// In particular, it will find the right vendored copy when in GOPATH mode.
|
||||||
|
func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
|
||||||
|
env, err := state.getEnv()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if env["GOMOD"] != "" {
|
||||||
|
return importPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
searchDir := sourceDir
|
||||||
|
for {
|
||||||
|
vendorDir := filepath.Join(searchDir, "vendor")
|
||||||
|
exists, ok := state.vendorDirs[vendorDir]
|
||||||
|
if !ok {
|
||||||
|
info, err := os.Stat(vendorDir)
|
||||||
|
exists = err == nil && info.IsDir()
|
||||||
|
state.vendorDirs[vendorDir] = exists
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
vendoredPath := filepath.Join(vendorDir, importPath)
|
||||||
|
if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
|
||||||
|
// We should probably check for .go files here, but shame on anyone who fools us.
|
||||||
|
path, ok, err := state.getPkgPath(vendoredPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We know we've hit the top of the filesystem when we Dir / and get /,
|
||||||
|
// or C:\ and get C:\, etc.
|
||||||
|
next := filepath.Dir(searchDir)
|
||||||
|
if next == searchDir {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
searchDir = next
|
||||||
|
}
|
||||||
|
return importPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
func hasTestFiles(p *Package) bool {
|
func hasTestFiles(p *Package) bool {
|
||||||
for _, f := range p.GoFiles {
|
for _, f := range p.GoFiles {
|
||||||
if strings.HasSuffix(f, "_test.go") {
|
if strings.HasSuffix(f, "_test.go") {
|
||||||
|
@ -194,44 +257,59 @@ func hasTestFiles(p *Package) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// determineRootDirs returns a mapping from directories code can be contained in to the
|
// determineRootDirs returns a mapping from absolute directories that could
|
||||||
// corresponding import path prefixes of those directories.
|
// contain code to their corresponding import path prefixes.
|
||||||
// Its result is used to try to determine the import path for a package containing
|
func (state *golistState) determineRootDirs() (map[string]string, error) {
|
||||||
// an overlay file.
|
env, err := state.getEnv()
|
||||||
func determineRootDirs(cfg *Config) map[string]string {
|
|
||||||
// Assume modules first:
|
|
||||||
out, err := invokeGo(cfg, "list", "-m", "-json", "all")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return determineRootDirsGOPATH(cfg)
|
return nil, err
|
||||||
|
}
|
||||||
|
if env["GOMOD"] != "" {
|
||||||
|
state.rootsOnce.Do(func() {
|
||||||
|
state.rootDirs, state.rootDirsError = state.determineRootDirsModules()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
state.rootsOnce.Do(func() {
|
||||||
|
state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return state.rootDirs, state.rootDirsError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (state *golistState) determineRootDirsModules() (map[string]string, error) {
|
||||||
|
out, err := state.invokeGo("list", "-m", "-json", "all")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
m := map[string]string{}
|
m := map[string]string{}
|
||||||
type jsonMod struct{ Path, Dir string }
|
type jsonMod struct{ Path, Dir string }
|
||||||
for dec := json.NewDecoder(out); dec.More(); {
|
for dec := json.NewDecoder(out); dec.More(); {
|
||||||
mod := new(jsonMod)
|
mod := new(jsonMod)
|
||||||
if err := dec.Decode(mod); err != nil {
|
if err := dec.Decode(mod); err != nil {
|
||||||
return m // Give up and return an empty map. Package won't be found for overlay.
|
return nil, err
|
||||||
}
|
}
|
||||||
if mod.Dir != "" && mod.Path != "" {
|
if mod.Dir != "" && mod.Path != "" {
|
||||||
// This is a valid module; add it to the map.
|
// This is a valid module; add it to the map.
|
||||||
m[mod.Dir] = mod.Path
|
absDir, err := filepath.Abs(mod.Dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m[absDir] = mod.Path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func determineRootDirsGOPATH(cfg *Config) map[string]string {
|
func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
|
||||||
m := map[string]string{}
|
m := map[string]string{}
|
||||||
out, err := invokeGo(cfg, "env", "GOPATH")
|
for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) {
|
||||||
if err != nil {
|
absDir, err := filepath.Abs(dir)
|
||||||
// Could not determine root dir mapping. Everything is best-effort, so just return an empty map.
|
if err != nil {
|
||||||
// When we try to find the import path for a directory, there will be no root-dir match and
|
return nil, err
|
||||||
// we'll give up.
|
}
|
||||||
return m
|
m[filepath.Join(absDir, "src")] = ""
|
||||||
}
|
}
|
||||||
for _, p := range filepath.SplitList(string(bytes.TrimSpace(out.Bytes()))) {
|
return m, nil
|
||||||
m[filepath.Join(p, "src")] = ""
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractImports(filename string, contents []byte) ([]string, error) {
|
func extractImports(filename string, contents []byte) ([]string, error) {
|
||||||
|
|
38
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
38
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
|
@ -23,6 +23,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/tools/go/gcexportdata"
|
"golang.org/x/tools/go/gcexportdata"
|
||||||
|
"golang.org/x/tools/internal/packagesinternal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A LoadMode controls the amount of detail to return when loading.
|
// A LoadMode controls the amount of detail to return when loading.
|
||||||
|
@ -34,6 +35,9 @@ import (
|
||||||
// Load may return more information than requested.
|
// Load may return more information than requested.
|
||||||
type LoadMode int
|
type LoadMode int
|
||||||
|
|
||||||
|
// TODO(matloob): When a V2 of go/packages is released, rename NeedExportsFile to
|
||||||
|
// NeedExportFile to make it consistent with the Package field it's adding.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// NeedName adds Name and PkgPath.
|
// NeedName adds Name and PkgPath.
|
||||||
NeedName LoadMode = 1 << iota
|
NeedName LoadMode = 1 << iota
|
||||||
|
@ -51,7 +55,7 @@ const (
|
||||||
// NeedDeps adds the fields requested by the LoadMode in the packages in Imports.
|
// NeedDeps adds the fields requested by the LoadMode in the packages in Imports.
|
||||||
NeedDeps
|
NeedDeps
|
||||||
|
|
||||||
// NeedExportsFile adds ExportsFile.
|
// NeedExportsFile adds ExportFile.
|
||||||
NeedExportsFile
|
NeedExportsFile
|
||||||
|
|
||||||
// NeedTypes adds Types, Fset, and IllTyped.
|
// NeedTypes adds Types, Fset, and IllTyped.
|
||||||
|
@ -160,7 +164,7 @@ type Config struct {
|
||||||
Tests bool
|
Tests bool
|
||||||
|
|
||||||
// Overlay provides a mapping of absolute file paths to file contents.
|
// Overlay provides a mapping of absolute file paths to file contents.
|
||||||
// If the file with the given path already exists, the parser will use the
|
// If the file with the given path already exists, the parser will use the
|
||||||
// alternative file contents provided by the map.
|
// alternative file contents provided by the map.
|
||||||
//
|
//
|
||||||
// Overlays provide incomplete support for when a given file doesn't
|
// Overlays provide incomplete support for when a given file doesn't
|
||||||
|
@ -292,6 +296,15 @@ type Package struct {
|
||||||
|
|
||||||
// TypesSizes provides the effective size function for types in TypesInfo.
|
// TypesSizes provides the effective size function for types in TypesInfo.
|
||||||
TypesSizes types.Sizes
|
TypesSizes types.Sizes
|
||||||
|
|
||||||
|
// forTest is the package under test, if any.
|
||||||
|
forTest string
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
packagesinternal.GetForTest = func(p interface{}) string {
|
||||||
|
return p.(*Package).forTest
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An Error describes a problem with a package's metadata, syntax, or types.
|
// An Error describes a problem with a package's metadata, syntax, or types.
|
||||||
|
@ -500,12 +513,23 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||||
if i, found := rootMap[pkg.ID]; found {
|
if i, found := rootMap[pkg.ID]; found {
|
||||||
rootIndex = i
|
rootIndex = i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overlays can invalidate export data.
|
||||||
|
// TODO(matloob): make this check fine-grained based on dependencies on overlaid files
|
||||||
|
exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe"
|
||||||
|
// This package needs type information if the caller requested types and the package is
|
||||||
|
// either a root, or it's a non-root and the user requested dependencies ...
|
||||||
|
needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0))
|
||||||
|
// This package needs source if the call requested source (or types info, which implies source)
|
||||||
|
// and the package is either a root, or itas a non- root and the user requested dependencies...
|
||||||
|
needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) ||
|
||||||
|
// ... or if we need types and the exportData is invalid. We fall back to (incompletely)
|
||||||
|
// typechecking packages from source if they fail to compile.
|
||||||
|
(ld.Mode&NeedTypes|NeedTypesInfo != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe"
|
||||||
lpkg := &loaderPackage{
|
lpkg := &loaderPackage{
|
||||||
Package: pkg,
|
Package: pkg,
|
||||||
needtypes: (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && ld.Mode&NeedDeps != 0 && rootIndex < 0) || rootIndex >= 0,
|
needtypes: needtypes,
|
||||||
needsrc: (ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && ld.Mode&NeedDeps != 0 && rootIndex < 0) || rootIndex >= 0 ||
|
needsrc: needsrc,
|
||||||
len(ld.Overlay) > 0 || // Overlays can invalidate export data. TODO(matloob): make this check fine-grained based on dependencies on overlaid files
|
|
||||||
pkg.ExportFile == "" && pkg.PkgPath != "unsafe",
|
|
||||||
}
|
}
|
||||||
ld.pkgs[lpkg.ID] = lpkg
|
ld.pkgs[lpkg.ID] = lpkg
|
||||||
if rootIndex >= 0 {
|
if rootIndex >= 0 {
|
||||||
|
@ -713,7 +737,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||||
// which would then require that such created packages be explicitly
|
// which would then require that such created packages be explicitly
|
||||||
// inserted back into the Import graph as a final step after export data loading.
|
// inserted back into the Import graph as a final step after export data loading.
|
||||||
// The Diamond test exercises this case.
|
// The Diamond test exercises this case.
|
||||||
if !lpkg.needtypes {
|
if !lpkg.needtypes && !lpkg.needsrc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !lpkg.needsrc {
|
if !lpkg.needsrc {
|
||||||
|
|
5
vendor/golang.org/x/tools/imports/forward.go
generated
vendored
5
vendor/golang.org/x/tools/imports/forward.go
generated
vendored
|
@ -4,6 +4,7 @@ package imports // import "golang.org/x/tools/imports"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go/build"
|
"go/build"
|
||||||
|
"os"
|
||||||
|
|
||||||
intimp "golang.org/x/tools/internal/imports"
|
intimp "golang.org/x/tools/internal/imports"
|
||||||
)
|
)
|
||||||
|
@ -42,6 +43,10 @@ func Process(filename string, src []byte, opt *Options) ([]byte, error) {
|
||||||
Env: &intimp.ProcessEnv{
|
Env: &intimp.ProcessEnv{
|
||||||
GOPATH: build.Default.GOPATH,
|
GOPATH: build.Default.GOPATH,
|
||||||
GOROOT: build.Default.GOROOT,
|
GOROOT: build.Default.GOROOT,
|
||||||
|
GOFLAGS: os.Getenv("GOFLAGS"),
|
||||||
|
GO111MODULE: os.Getenv("GO111MODULE"),
|
||||||
|
GOPROXY: os.Getenv("GOPROXY"),
|
||||||
|
GOSUMDB: os.Getenv("GOSUMDB"),
|
||||||
Debug: Debug,
|
Debug: Debug,
|
||||||
LocalPrefix: LocalPrefix,
|
LocalPrefix: LocalPrefix,
|
||||||
},
|
},
|
||||||
|
|
5
vendor/golang.org/x/tools/internal/gopathwalk/walk.go
generated
vendored
5
vendor/golang.org/x/tools/internal/gopathwalk/walk.go
generated
vendored
|
@ -77,6 +77,7 @@ func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// walkDir creates a walker and starts fastwalk with this walker.
|
||||||
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
|
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
|
||||||
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
|
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
|
||||||
if opts.Debug {
|
if opts.Debug {
|
||||||
|
@ -114,7 +115,7 @@ type walker struct {
|
||||||
ignoredDirs []os.FileInfo // The ignored directories, loaded from .goimportsignore files.
|
ignoredDirs []os.FileInfo // The ignored directories, loaded from .goimportsignore files.
|
||||||
}
|
}
|
||||||
|
|
||||||
// init initializes the walker based on its Options.
|
// init initializes the walker based on its Options
|
||||||
func (w *walker) init() {
|
func (w *walker) init() {
|
||||||
var ignoredPaths []string
|
var ignoredPaths []string
|
||||||
if w.root.Type == RootModuleCache {
|
if w.root.Type == RootModuleCache {
|
||||||
|
@ -167,6 +168,7 @@ func (w *walker) getIgnoredDirs(path string) []string {
|
||||||
return ignoredDirs
|
return ignoredDirs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shouldSkipDir reports whether the file should be skipped or not.
|
||||||
func (w *walker) shouldSkipDir(fi os.FileInfo, dir string) bool {
|
func (w *walker) shouldSkipDir(fi os.FileInfo, dir string) bool {
|
||||||
for _, ignoredDir := range w.ignoredDirs {
|
for _, ignoredDir := range w.ignoredDirs {
|
||||||
if os.SameFile(fi, ignoredDir) {
|
if os.SameFile(fi, ignoredDir) {
|
||||||
|
@ -180,6 +182,7 @@ func (w *walker) shouldSkipDir(fi os.FileInfo, dir string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// walk walks through the given path.
|
||||||
func (w *walker) walk(path string, typ os.FileMode) error {
|
func (w *walker) walk(path string, typ os.FileMode) error {
|
||||||
dir := filepath.Dir(path)
|
dir := filepath.Dir(path)
|
||||||
if typ.IsRegular() {
|
if typ.IsRegular() {
|
||||||
|
|
585
vendor/golang.org/x/tools/internal/imports/fix.go
generated
vendored
585
vendor/golang.org/x/tools/internal/imports/fix.go
generated
vendored
|
@ -27,7 +27,6 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
"golang.org/x/tools/go/packages"
|
|
||||||
"golang.org/x/tools/internal/gopathwalk"
|
"golang.org/x/tools/internal/gopathwalk"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -82,7 +81,8 @@ type ImportFix struct {
|
||||||
// IdentName is the identifier that this fix will add or remove.
|
// IdentName is the identifier that this fix will add or remove.
|
||||||
IdentName string
|
IdentName string
|
||||||
// FixType is the type of fix this is (AddImport, DeleteImport, SetImportName).
|
// FixType is the type of fix this is (AddImport, DeleteImport, SetImportName).
|
||||||
FixType ImportFixType
|
FixType ImportFixType
|
||||||
|
Relevance int // see pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
// An ImportInfo represents a single import statement.
|
// An ImportInfo represents a single import statement.
|
||||||
|
@ -585,62 +585,86 @@ func getFixes(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv
|
||||||
return fixes, nil
|
return fixes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCandidatePkgs returns the list of pkgs that are accessible from filename,
|
// Highest relevance, used for the standard library. Chosen arbitrarily to
|
||||||
// optionall filtered to only packages named pkgName.
|
// match pre-existing gopls code.
|
||||||
func getCandidatePkgs(pkgName, filename string, env *ProcessEnv) ([]*pkg, error) {
|
const MaxRelevance = 7
|
||||||
// TODO(heschi): filter out current package. (Don't forget x_test can import x.)
|
|
||||||
|
|
||||||
var result []*pkg
|
// getCandidatePkgs works with the passed callback to find all acceptable packages.
|
||||||
|
// It deduplicates by import path, and uses a cached stdlib rather than reading
|
||||||
|
// from disk.
|
||||||
|
func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filename, filePkg string, env *ProcessEnv) error {
|
||||||
|
notSelf := func(p *pkg) bool {
|
||||||
|
return p.packageName != filePkg || p.dir != filepath.Dir(filename)
|
||||||
|
}
|
||||||
// Start off with the standard library.
|
// Start off with the standard library.
|
||||||
for importPath := range stdlib {
|
for importPath, exports := range stdlib {
|
||||||
if pkgName != "" && path.Base(importPath) != pkgName {
|
p := &pkg{
|
||||||
continue
|
|
||||||
}
|
|
||||||
result = append(result, &pkg{
|
|
||||||
dir: filepath.Join(env.GOROOT, "src", importPath),
|
dir: filepath.Join(env.GOROOT, "src", importPath),
|
||||||
importPathShort: importPath,
|
importPathShort: importPath,
|
||||||
packageName: path.Base(importPath),
|
packageName: path.Base(importPath),
|
||||||
relevance: 0,
|
relevance: MaxRelevance,
|
||||||
})
|
}
|
||||||
}
|
if notSelf(p) && wrappedCallback.packageNameLoaded(p) {
|
||||||
|
wrappedCallback.exportsLoaded(p, exports)
|
||||||
// Exclude goroot results -- getting them is relatively expensive, not cached,
|
}
|
||||||
// and generally redundant with the in-memory version.
|
|
||||||
exclude := []gopathwalk.RootType{gopathwalk.RootGOROOT}
|
|
||||||
// Only the go/packages resolver uses the first argument, and nobody uses that resolver.
|
|
||||||
scannedPkgs, err := env.GetResolver().scan(nil, true, exclude)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mu sync.Mutex
|
||||||
dupCheck := map[string]struct{}{}
|
dupCheck := map[string]struct{}{}
|
||||||
for _, pkg := range scannedPkgs {
|
|
||||||
if pkgName != "" && pkg.packageName != pkgName {
|
scanFilter := &scanCallback{
|
||||||
continue
|
rootFound: func(root gopathwalk.Root) bool {
|
||||||
}
|
// Exclude goroot results -- getting them is relatively expensive, not cached,
|
||||||
if !canUse(filename, pkg.dir) {
|
// and generally redundant with the in-memory version.
|
||||||
continue
|
return root.Type != gopathwalk.RootGOROOT && wrappedCallback.rootFound(root)
|
||||||
}
|
},
|
||||||
if _, ok := dupCheck[pkg.importPathShort]; ok {
|
dirFound: wrappedCallback.dirFound,
|
||||||
continue
|
packageNameLoaded: func(pkg *pkg) bool {
|
||||||
}
|
mu.Lock()
|
||||||
dupCheck[pkg.importPathShort] = struct{}{}
|
defer mu.Unlock()
|
||||||
result = append(result, pkg)
|
if _, ok := dupCheck[pkg.importPathShort]; ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
dupCheck[pkg.importPathShort] = struct{}{}
|
||||||
|
return notSelf(pkg) && wrappedCallback.packageNameLoaded(pkg)
|
||||||
|
},
|
||||||
|
exportsLoaded: func(pkg *pkg, exports []string) {
|
||||||
|
// If we're an x_test, load the package under test's test variant.
|
||||||
|
if strings.HasSuffix(filePkg, "_test") && pkg.dir == filepath.Dir(filename) {
|
||||||
|
var err error
|
||||||
|
_, exports, err = loadExportsFromFiles(ctx, env, pkg.dir, true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrappedCallback.exportsLoaded(pkg, exports)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
return env.GetResolver().scan(ctx, scanFilter)
|
||||||
|
}
|
||||||
|
|
||||||
// Sort first by relevance, then by package name, with import path as a tiebreaker.
|
func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) map[string]int {
|
||||||
sort.Slice(result, func(i, j int) bool {
|
result := make(map[string]int)
|
||||||
pi, pj := result[i], result[j]
|
for _, path := range paths {
|
||||||
if pi.relevance != pj.relevance {
|
result[path] = env.GetResolver().scoreImportPath(ctx, path)
|
||||||
return pi.relevance < pj.relevance
|
}
|
||||||
}
|
return result
|
||||||
if pi.packageName != pj.packageName {
|
}
|
||||||
return pi.packageName < pj.packageName
|
|
||||||
}
|
|
||||||
return pi.importPathShort < pj.importPathShort
|
|
||||||
})
|
|
||||||
|
|
||||||
return result, nil
|
func PrimeCache(ctx context.Context, env *ProcessEnv) error {
|
||||||
|
// Fully scan the disk for directories, but don't actually read any Go files.
|
||||||
|
callback := &scanCallback{
|
||||||
|
rootFound: func(gopathwalk.Root) bool {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
dirFound: func(pkg *pkg) bool {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
packageNameLoaded: func(pkg *pkg) bool {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return getCandidatePkgs(ctx, callback, "", "", env)
|
||||||
}
|
}
|
||||||
|
|
||||||
func candidateImportName(pkg *pkg) string {
|
func candidateImportName(pkg *pkg) string {
|
||||||
|
@ -651,23 +675,37 @@ func candidateImportName(pkg *pkg) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAllCandidates gets all of the candidates to be imported, regardless of if they are needed.
|
// getAllCandidates gets all of the candidates to be imported, regardless of if they are needed.
|
||||||
func getAllCandidates(filename string, env *ProcessEnv) ([]ImportFix, error) {
|
func getAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error {
|
||||||
pkgs, err := getCandidatePkgs("", filename, env)
|
callback := &scanCallback{
|
||||||
if err != nil {
|
rootFound: func(gopathwalk.Root) bool {
|
||||||
return nil, err
|
return true
|
||||||
|
},
|
||||||
|
dirFound: func(pkg *pkg) bool {
|
||||||
|
if !canUse(filename, pkg.dir) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Try the assumed package name first, then a simpler path match
|
||||||
|
// in case of packages named vN, which are not uncommon.
|
||||||
|
return strings.HasPrefix(ImportPathToAssumedName(pkg.importPathShort), searchPrefix) ||
|
||||||
|
strings.HasPrefix(path.Base(pkg.importPathShort), searchPrefix)
|
||||||
|
},
|
||||||
|
packageNameLoaded: func(pkg *pkg) bool {
|
||||||
|
if !strings.HasPrefix(pkg.packageName, searchPrefix) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
wrapped(ImportFix{
|
||||||
|
StmtInfo: ImportInfo{
|
||||||
|
ImportPath: pkg.importPathShort,
|
||||||
|
Name: candidateImportName(pkg),
|
||||||
|
},
|
||||||
|
IdentName: pkg.packageName,
|
||||||
|
FixType: AddImport,
|
||||||
|
Relevance: pkg.relevance,
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
},
|
||||||
}
|
}
|
||||||
result := make([]ImportFix, 0, len(pkgs))
|
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
|
||||||
for _, pkg := range pkgs {
|
|
||||||
result = append(result, ImportFix{
|
|
||||||
StmtInfo: ImportInfo{
|
|
||||||
ImportPath: pkg.importPathShort,
|
|
||||||
Name: candidateImportName(pkg),
|
|
||||||
},
|
|
||||||
IdentName: pkg.packageName,
|
|
||||||
FixType: AddImport,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A PackageExport is a package and its exports.
|
// A PackageExport is a package and its exports.
|
||||||
|
@ -676,42 +714,34 @@ type PackageExport struct {
|
||||||
Exports []string
|
Exports []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPackageExports(completePackage, filename string, env *ProcessEnv) ([]PackageExport, error) {
|
func getPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error {
|
||||||
pkgs, err := getCandidatePkgs(completePackage, filename, env)
|
callback := &scanCallback{
|
||||||
if err != nil {
|
rootFound: func(gopathwalk.Root) bool {
|
||||||
return nil, err
|
return true
|
||||||
|
},
|
||||||
|
dirFound: func(pkg *pkg) bool {
|
||||||
|
return pkgIsCandidate(filename, references{searchPkg: nil}, pkg)
|
||||||
|
},
|
||||||
|
packageNameLoaded: func(pkg *pkg) bool {
|
||||||
|
return pkg.packageName == searchPkg
|
||||||
|
},
|
||||||
|
exportsLoaded: func(pkg *pkg, exports []string) {
|
||||||
|
sort.Strings(exports)
|
||||||
|
wrapped(PackageExport{
|
||||||
|
Fix: &ImportFix{
|
||||||
|
StmtInfo: ImportInfo{
|
||||||
|
ImportPath: pkg.importPathShort,
|
||||||
|
Name: candidateImportName(pkg),
|
||||||
|
},
|
||||||
|
IdentName: pkg.packageName,
|
||||||
|
FixType: AddImport,
|
||||||
|
Relevance: pkg.relevance,
|
||||||
|
},
|
||||||
|
Exports: exports,
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
|
||||||
results := make([]PackageExport, 0, len(pkgs))
|
|
||||||
for _, pkg := range pkgs {
|
|
||||||
fix := &ImportFix{
|
|
||||||
StmtInfo: ImportInfo{
|
|
||||||
ImportPath: pkg.importPathShort,
|
|
||||||
Name: candidateImportName(pkg),
|
|
||||||
},
|
|
||||||
IdentName: pkg.packageName,
|
|
||||||
FixType: AddImport,
|
|
||||||
}
|
|
||||||
var exports []string
|
|
||||||
if e, ok := stdlib[pkg.importPathShort]; ok {
|
|
||||||
exports = e
|
|
||||||
} else {
|
|
||||||
exports, err = loadExportsForPackage(context.Background(), env, completePackage, pkg)
|
|
||||||
if err != nil {
|
|
||||||
if env.Debug {
|
|
||||||
env.Logf("while completing %q, error loading exports from %q: %v", completePackage, pkg.importPathShort, err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Strings(exports)
|
|
||||||
results = append(results, PackageExport{
|
|
||||||
Fix: fix,
|
|
||||||
Exports: exports,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return results, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessEnv contains environment variables and settings that affect the use of
|
// ProcessEnv contains environment variables and settings that affect the use of
|
||||||
|
@ -725,15 +755,19 @@ type ProcessEnv struct {
|
||||||
GOPATH, GOROOT, GO111MODULE, GOPROXY, GOFLAGS, GOSUMDB string
|
GOPATH, GOROOT, GO111MODULE, GOPROXY, GOFLAGS, GOSUMDB string
|
||||||
WorkingDir string
|
WorkingDir string
|
||||||
|
|
||||||
// If true, use go/packages regardless of the environment.
|
|
||||||
ForceGoPackages bool
|
|
||||||
|
|
||||||
// Logf is the default logger for the ProcessEnv.
|
// Logf is the default logger for the ProcessEnv.
|
||||||
Logf func(format string, args ...interface{})
|
Logf func(format string, args ...interface{})
|
||||||
|
|
||||||
resolver Resolver
|
resolver Resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CopyConfig copies the env's configuration into a new env.
|
||||||
|
func (e *ProcessEnv) CopyConfig() *ProcessEnv {
|
||||||
|
copy := *e
|
||||||
|
copy.resolver = nil
|
||||||
|
return ©
|
||||||
|
}
|
||||||
|
|
||||||
func (e *ProcessEnv) env() []string {
|
func (e *ProcessEnv) env() []string {
|
||||||
env := os.Environ()
|
env := os.Environ()
|
||||||
add := func(k, v string) {
|
add := func(k, v string) {
|
||||||
|
@ -757,39 +791,34 @@ func (e *ProcessEnv) GetResolver() Resolver {
|
||||||
if e.resolver != nil {
|
if e.resolver != nil {
|
||||||
return e.resolver
|
return e.resolver
|
||||||
}
|
}
|
||||||
if e.ForceGoPackages {
|
|
||||||
e.resolver = &goPackagesResolver{env: e}
|
|
||||||
return e.resolver
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := e.invokeGo("env", "GOMOD")
|
out, err := e.invokeGo("env", "GOMOD")
|
||||||
if err != nil || len(bytes.TrimSpace(out.Bytes())) == 0 {
|
if err != nil || len(bytes.TrimSpace(out.Bytes())) == 0 {
|
||||||
e.resolver = &gopathResolver{env: e}
|
e.resolver = newGopathResolver(e)
|
||||||
return e.resolver
|
return e.resolver
|
||||||
}
|
}
|
||||||
e.resolver = &ModuleResolver{env: e}
|
e.resolver = newModuleResolver(e)
|
||||||
return e.resolver
|
return e.resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ProcessEnv) newPackagesConfig(mode packages.LoadMode) *packages.Config {
|
|
||||||
return &packages.Config{
|
|
||||||
Mode: mode,
|
|
||||||
Dir: e.WorkingDir,
|
|
||||||
Env: e.env(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ProcessEnv) buildContext() *build.Context {
|
func (e *ProcessEnv) buildContext() *build.Context {
|
||||||
ctx := build.Default
|
ctx := build.Default
|
||||||
ctx.GOROOT = e.GOROOT
|
ctx.GOROOT = e.GOROOT
|
||||||
ctx.GOPATH = e.GOPATH
|
ctx.GOPATH = e.GOPATH
|
||||||
|
|
||||||
// As of Go 1.14, build.Context has a WorkingDir field
|
// As of Go 1.14, build.Context has a Dir field
|
||||||
// (see golang.org/issue/34860).
|
// (see golang.org/issue/34860).
|
||||||
// Populate it only if present.
|
// Populate it only if present.
|
||||||
if wd := reflect.ValueOf(&ctx).Elem().FieldByName("WorkingDir"); wd.IsValid() && wd.Kind() == reflect.String {
|
rc := reflect.ValueOf(&ctx).Elem()
|
||||||
wd.SetString(e.WorkingDir)
|
dir := rc.FieldByName("Dir")
|
||||||
|
if !dir.IsValid() {
|
||||||
|
// Working drafts of Go 1.14 named the field "WorkingDir" instead.
|
||||||
|
// TODO(bcmills): Remove this case after the Go 1.14 beta has been released.
|
||||||
|
dir = rc.FieldByName("WorkingDir")
|
||||||
}
|
}
|
||||||
|
if dir.IsValid() && dir.Kind() == reflect.String {
|
||||||
|
dir.SetString(e.WorkingDir)
|
||||||
|
}
|
||||||
|
|
||||||
return &ctx
|
return &ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,94 +877,65 @@ func addStdlibCandidates(pass *pass, refs references) {
|
||||||
type Resolver interface {
|
type Resolver interface {
|
||||||
// loadPackageNames loads the package names in importPaths.
|
// loadPackageNames loads the package names in importPaths.
|
||||||
loadPackageNames(importPaths []string, srcDir string) (map[string]string, error)
|
loadPackageNames(importPaths []string, srcDir string) (map[string]string, error)
|
||||||
// scan finds (at least) the packages satisfying refs. If loadNames is true,
|
// scan works with callback to search for packages. See scanCallback for details.
|
||||||
// package names will be set on the results, and dirs whose package name
|
scan(ctx context.Context, callback *scanCallback) error
|
||||||
// could not be determined will be excluded.
|
|
||||||
scan(refs references, loadNames bool, exclude []gopathwalk.RootType) ([]*pkg, error)
|
|
||||||
// loadExports returns the set of exported symbols in the package at dir.
|
// loadExports returns the set of exported symbols in the package at dir.
|
||||||
// loadExports may be called concurrently.
|
// loadExports may be called concurrently.
|
||||||
loadExports(ctx context.Context, pkg *pkg) (string, []string, error)
|
loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error)
|
||||||
|
// scoreImportPath returns the relevance for an import path.
|
||||||
|
scoreImportPath(ctx context.Context, path string) int
|
||||||
|
|
||||||
ClearForNewScan()
|
ClearForNewScan()
|
||||||
}
|
}
|
||||||
|
|
||||||
// gopackagesResolver implements resolver for GOPATH and module workspaces using go/packages.
|
// A scanCallback controls a call to scan and receives its results.
|
||||||
type goPackagesResolver struct {
|
// In general, minor errors will be silently discarded; a user should not
|
||||||
env *ProcessEnv
|
// expect to receive a full series of calls for everything.
|
||||||
}
|
type scanCallback struct {
|
||||||
|
// rootFound is called before scanning a new root dir. If it returns true,
|
||||||
func (r *goPackagesResolver) ClearForNewScan() {}
|
// the root will be scanned. Returning false will not necessarily prevent
|
||||||
|
// directories from that root making it to dirFound.
|
||||||
func (r *goPackagesResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
rootFound func(gopathwalk.Root) bool
|
||||||
if len(importPaths) == 0 {
|
// dirFound is called when a directory is found that is possibly a Go package.
|
||||||
return nil, nil
|
// pkg will be populated with everything except packageName.
|
||||||
}
|
// If it returns true, the package's name will be loaded.
|
||||||
cfg := r.env.newPackagesConfig(packages.LoadFiles)
|
dirFound func(pkg *pkg) bool
|
||||||
pkgs, err := packages.Load(cfg, importPaths...)
|
// packageNameLoaded is called when a package is found and its name is loaded.
|
||||||
if err != nil {
|
// If it returns true, the package's exports will be loaded.
|
||||||
return nil, err
|
packageNameLoaded func(pkg *pkg) bool
|
||||||
}
|
// exportsLoaded is called when a package's exports have been loaded.
|
||||||
names := map[string]string{}
|
exportsLoaded func(pkg *pkg, exports []string)
|
||||||
for _, pkg := range pkgs {
|
|
||||||
names[VendorlessPath(pkg.PkgPath)] = pkg.Name
|
|
||||||
}
|
|
||||||
// We may not have found all the packages. Guess the rest.
|
|
||||||
for _, path := range importPaths {
|
|
||||||
if _, ok := names[path]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
names[path] = ImportPathToAssumedName(path)
|
|
||||||
}
|
|
||||||
return names, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *goPackagesResolver) scan(refs references, _ bool, _ []gopathwalk.RootType) ([]*pkg, error) {
|
|
||||||
var loadQueries []string
|
|
||||||
for pkgName := range refs {
|
|
||||||
loadQueries = append(loadQueries, "iamashamedtousethedisabledqueryname="+pkgName)
|
|
||||||
}
|
|
||||||
sort.Strings(loadQueries)
|
|
||||||
cfg := r.env.newPackagesConfig(packages.LoadFiles)
|
|
||||||
goPackages, err := packages.Load(cfg, loadQueries...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var scan []*pkg
|
|
||||||
for _, goPackage := range goPackages {
|
|
||||||
scan = append(scan, &pkg{
|
|
||||||
dir: filepath.Dir(goPackage.CompiledGoFiles[0]),
|
|
||||||
importPathShort: VendorlessPath(goPackage.PkgPath),
|
|
||||||
goPackage: goPackage,
|
|
||||||
packageName: goPackage.Name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return scan, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *goPackagesResolver) loadExports(ctx context.Context, pkg *pkg) (string, []string, error) {
|
|
||||||
if pkg.goPackage == nil {
|
|
||||||
return "", nil, fmt.Errorf("goPackage not set")
|
|
||||||
}
|
|
||||||
var exports []string
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
for _, fname := range pkg.goPackage.CompiledGoFiles {
|
|
||||||
f, err := parser.ParseFile(fset, fname, nil, 0)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, fmt.Errorf("parsing %s: %v", fname, err)
|
|
||||||
}
|
|
||||||
for name := range f.Scope.Objects {
|
|
||||||
if ast.IsExported(name) {
|
|
||||||
exports = append(exports, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pkg.goPackage.Name, exports, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addExternalCandidates(pass *pass, refs references, filename string) error {
|
func addExternalCandidates(pass *pass, refs references, filename string) error {
|
||||||
dirScan, err := pass.env.GetResolver().scan(refs, false, nil)
|
var mu sync.Mutex
|
||||||
|
found := make(map[string][]pkgDistance)
|
||||||
|
callback := &scanCallback{
|
||||||
|
rootFound: func(gopathwalk.Root) bool {
|
||||||
|
return true // We want everything.
|
||||||
|
},
|
||||||
|
dirFound: func(pkg *pkg) bool {
|
||||||
|
return pkgIsCandidate(filename, refs, pkg)
|
||||||
|
},
|
||||||
|
packageNameLoaded: func(pkg *pkg) bool {
|
||||||
|
if _, want := refs[pkg.packageName]; !want {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pkg.dir == pass.srcDir && pass.f.Name.Name == pkg.packageName {
|
||||||
|
// The candidate is in the same directory and has the
|
||||||
|
// same package name. Don't try to import ourselves.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !canUse(filename, pkg.dir) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
found[pkg.packageName] = append(found[pkg.packageName], pkgDistance{pkg, distance(pass.srcDir, pkg.dir)})
|
||||||
|
return false // We'll do our own loading after we sort.
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := pass.env.GetResolver().scan(context.Background(), callback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -962,7 +962,7 @@ func addExternalCandidates(pass *pass, refs references, filename string) error {
|
||||||
go func(pkgName string, symbols map[string]bool) {
|
go func(pkgName string, symbols map[string]bool) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
found, err := findImport(ctx, pass, dirScan, pkgName, symbols, filename)
|
found, err := findImport(ctx, pass, found[pkgName], pkgName, symbols, filename)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
firstErrOnce.Do(func() {
|
firstErrOnce.Do(func() {
|
||||||
|
@ -1033,24 +1033,36 @@ func ImportPathToAssumedName(importPath string) string {
|
||||||
|
|
||||||
// gopathResolver implements resolver for GOPATH workspaces.
|
// gopathResolver implements resolver for GOPATH workspaces.
|
||||||
type gopathResolver struct {
|
type gopathResolver struct {
|
||||||
env *ProcessEnv
|
env *ProcessEnv
|
||||||
cache *dirInfoCache
|
walked bool
|
||||||
|
cache *dirInfoCache
|
||||||
|
scanSema chan struct{} // scanSema prevents concurrent scans.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) init() {
|
func newGopathResolver(env *ProcessEnv) *gopathResolver {
|
||||||
if r.cache == nil {
|
r := &gopathResolver{
|
||||||
r.cache = &dirInfoCache{
|
env: env,
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
cache: &dirInfoCache{
|
||||||
}
|
dirs: map[string]*directoryPackageInfo{},
|
||||||
|
listeners: map[*int]cacheListener{},
|
||||||
|
},
|
||||||
|
scanSema: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
|
r.scanSema <- struct{}{}
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) ClearForNewScan() {
|
func (r *gopathResolver) ClearForNewScan() {
|
||||||
r.cache = nil
|
<-r.scanSema
|
||||||
|
r.cache = &dirInfoCache{
|
||||||
|
dirs: map[string]*directoryPackageInfo{},
|
||||||
|
listeners: map[*int]cacheListener{},
|
||||||
|
}
|
||||||
|
r.walked = false
|
||||||
|
r.scanSema <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
||||||
r.init()
|
|
||||||
names := map[string]string{}
|
names := map[string]string{}
|
||||||
for _, path := range importPaths {
|
for _, path := range importPaths {
|
||||||
names[path] = importPathToName(r.env, path, srcDir)
|
names[path] = importPathToName(r.env, path, srcDir)
|
||||||
|
@ -1130,7 +1142,6 @@ func packageDirToName(dir string) (packageName string, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type pkg struct {
|
type pkg struct {
|
||||||
goPackage *packages.Package
|
|
||||||
dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http")
|
dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http")
|
||||||
importPathShort string // vendorless import path ("net/http", "a/b")
|
importPathShort string // vendorless import path ("net/http", "a/b")
|
||||||
packageName string // package name loaded from source if requested
|
packageName string // package name loaded from source if requested
|
||||||
|
@ -1178,8 +1189,7 @@ func distance(basepath, targetpath string) int {
|
||||||
return strings.Count(p, string(filepath.Separator)) + 1
|
return strings.Count(p, string(filepath.Separator)) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) scan(_ references, loadNames bool, exclude []gopathwalk.RootType) ([]*pkg, error) {
|
func (r *gopathResolver) scan(ctx context.Context, callback *scanCallback) error {
|
||||||
r.init()
|
|
||||||
add := func(root gopathwalk.Root, dir string) {
|
add := func(root gopathwalk.Root, dir string) {
|
||||||
// We assume cached directories have not changed. We can skip them and their
|
// We assume cached directories have not changed. We can skip them and their
|
||||||
// children.
|
// children.
|
||||||
|
@ -1196,56 +1206,84 @@ func (r *gopathResolver) scan(_ references, loadNames bool, exclude []gopathwalk
|
||||||
}
|
}
|
||||||
r.cache.Store(dir, info)
|
r.cache.Store(dir, info)
|
||||||
}
|
}
|
||||||
roots := filterRoots(gopathwalk.SrcDirsRoots(r.env.buildContext()), exclude)
|
processDir := func(info directoryPackageInfo) {
|
||||||
gopathwalk.Walk(roots, add, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: false})
|
// Skip this directory if we were not able to get the package information successfully.
|
||||||
var result []*pkg
|
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
||||||
for _, dir := range r.cache.Keys() {
|
return
|
||||||
info, ok := r.cache.Load(dir)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if loadNames {
|
|
||||||
var err error
|
|
||||||
info, err = r.cache.CachePackageName(info)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pkg{
|
p := &pkg{
|
||||||
importPathShort: info.nonCanonicalImportPath,
|
importPathShort: info.nonCanonicalImportPath,
|
||||||
dir: dir,
|
dir: info.dir,
|
||||||
relevance: 1,
|
relevance: MaxRelevance - 1,
|
||||||
packageName: info.packageName,
|
|
||||||
}
|
}
|
||||||
if info.rootType == gopathwalk.RootGOROOT {
|
if info.rootType == gopathwalk.RootGOROOT {
|
||||||
p.relevance = 0
|
p.relevance = MaxRelevance
|
||||||
|
}
|
||||||
|
|
||||||
|
if !callback.dirFound(p) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
p.packageName, err = r.cache.CachePackageName(info)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !callback.packageNameLoaded(p) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, exports, err := r.loadExports(ctx, p, false); err == nil {
|
||||||
|
callback.exportsLoaded(p, exports)
|
||||||
}
|
}
|
||||||
result = append(result, p)
|
|
||||||
}
|
}
|
||||||
return result, nil
|
stop := r.cache.ScanAndListen(ctx, processDir)
|
||||||
|
defer stop()
|
||||||
|
// The callback is not necessarily safe to use in the goroutine below. Process roots eagerly.
|
||||||
|
roots := filterRoots(gopathwalk.SrcDirsRoots(r.env.buildContext()), callback.rootFound)
|
||||||
|
// We can't cancel walks, because we need them to finish to have a usable
|
||||||
|
// cache. Instead, run them in a separate goroutine and detach.
|
||||||
|
scanDone := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-r.scanSema:
|
||||||
|
}
|
||||||
|
defer func() { r.scanSema <- struct{}{} }()
|
||||||
|
gopathwalk.Walk(roots, add, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: false})
|
||||||
|
close(scanDone)
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
case <-scanDone:
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterRoots(roots []gopathwalk.Root, exclude []gopathwalk.RootType) []gopathwalk.Root {
|
func (r *gopathResolver) scoreImportPath(ctx context.Context, path string) int {
|
||||||
|
if _, ok := stdlib[path]; ok {
|
||||||
|
return MaxRelevance
|
||||||
|
}
|
||||||
|
return MaxRelevance - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterRoots(roots []gopathwalk.Root, include func(gopathwalk.Root) bool) []gopathwalk.Root {
|
||||||
var result []gopathwalk.Root
|
var result []gopathwalk.Root
|
||||||
outer:
|
|
||||||
for _, root := range roots {
|
for _, root := range roots {
|
||||||
for _, i := range exclude {
|
if !include(root) {
|
||||||
if i == root.Type {
|
continue
|
||||||
continue outer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result = append(result, root)
|
result = append(result, root)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) loadExports(ctx context.Context, pkg *pkg) (string, []string, error) {
|
func (r *gopathResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) {
|
||||||
r.init()
|
if info, ok := r.cache.Load(pkg.dir); ok && !includeTest {
|
||||||
if info, ok := r.cache.Load(pkg.dir); ok {
|
|
||||||
return r.cache.CacheExports(ctx, r.env, info)
|
return r.cache.CacheExports(ctx, r.env, info)
|
||||||
}
|
}
|
||||||
return loadExportsFromFiles(ctx, r.env, pkg.dir)
|
return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VendorlessPath returns the devendorized version of the import path ipath.
|
// VendorlessPath returns the devendorized version of the import path ipath.
|
||||||
|
@ -1261,7 +1299,7 @@ func VendorlessPath(ipath string) string {
|
||||||
return ipath
|
return ipath
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string) (string, []string, error) {
|
func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, includeTest bool) (string, []string, error) {
|
||||||
var exports []string
|
var exports []string
|
||||||
|
|
||||||
// Look for non-test, buildable .go files which could provide exports.
|
// Look for non-test, buildable .go files which could provide exports.
|
||||||
|
@ -1272,7 +1310,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string) (str
|
||||||
var files []os.FileInfo
|
var files []os.FileInfo
|
||||||
for _, fi := range all {
|
for _, fi := range all {
|
||||||
name := fi.Name()
|
name := fi.Name()
|
||||||
if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
|
if !strings.HasSuffix(name, ".go") || (!includeTest && strings.HasSuffix(name, "_test.go")) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
match, err := env.buildContext().MatchFile(dir, fi.Name())
|
match, err := env.buildContext().MatchFile(dir, fi.Name())
|
||||||
|
@ -1305,6 +1343,10 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string) (str
|
||||||
// handled by MatchFile above.
|
// handled by MatchFile above.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if includeTest && strings.HasSuffix(f.Name.Name, "_test") {
|
||||||
|
// x_test package. We want internal test files only.
|
||||||
|
continue
|
||||||
|
}
|
||||||
pkgName = f.Name.Name
|
pkgName = f.Name.Name
|
||||||
for name := range f.Scope.Objects {
|
for name := range f.Scope.Objects {
|
||||||
if ast.IsExported(name) {
|
if ast.IsExported(name) {
|
||||||
|
@ -1323,29 +1365,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string) (str
|
||||||
|
|
||||||
// findImport searches for a package with the given symbols.
|
// findImport searches for a package with the given symbols.
|
||||||
// If no package is found, findImport returns ("", false, nil)
|
// If no package is found, findImport returns ("", false, nil)
|
||||||
func findImport(ctx context.Context, pass *pass, dirScan []*pkg, pkgName string, symbols map[string]bool, filename string) (*pkg, error) {
|
func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgName string, symbols map[string]bool, filename string) (*pkg, error) {
|
||||||
pkgDir, err := filepath.Abs(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pkgDir = filepath.Dir(pkgDir)
|
|
||||||
|
|
||||||
// Find candidate packages, looking only at their directory names first.
|
|
||||||
var candidates []pkgDistance
|
|
||||||
for _, pkg := range dirScan {
|
|
||||||
if pkg.dir == pkgDir && pass.f.Name.Name == pkgName {
|
|
||||||
// The candidate is in the same directory and has the
|
|
||||||
// same package name. Don't try to import ourselves.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if pkgIsCandidate(filename, pkgName, pkg) {
|
|
||||||
candidates = append(candidates, pkgDistance{
|
|
||||||
pkg: pkg,
|
|
||||||
distance: distance(pkgDir, pkg.dir),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the candidates by their import package length,
|
// Sort the candidates by their import package length,
|
||||||
// assuming that shorter package names are better than long
|
// assuming that shorter package names are better than long
|
||||||
// ones. Note that this sorts by the de-vendored name, so
|
// ones. Note that this sorts by the de-vendored name, so
|
||||||
|
@ -1358,7 +1378,6 @@ func findImport(ctx context.Context, pass *pass, dirScan []*pkg, pkgName string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect exports for packages with matching names.
|
// Collect exports for packages with matching names.
|
||||||
|
|
||||||
rescv := make([]chan *pkg, len(candidates))
|
rescv := make([]chan *pkg, len(candidates))
|
||||||
for i := range candidates {
|
for i := range candidates {
|
||||||
rescv[i] = make(chan *pkg, 1)
|
rescv[i] = make(chan *pkg, 1)
|
||||||
|
@ -1393,7 +1412,9 @@ func findImport(ctx context.Context, pass *pass, dirScan []*pkg, pkgName string,
|
||||||
if pass.env.Debug {
|
if pass.env.Debug {
|
||||||
pass.env.Logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName)
|
pass.env.Logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName)
|
||||||
}
|
}
|
||||||
exports, err := loadExportsForPackage(ctx, pass.env, pkgName, c.pkg)
|
// If we're an x_test, load the package under test's test variant.
|
||||||
|
includeTest := strings.HasSuffix(pass.f.Name.Name, "_test") && c.pkg.dir == pass.srcDir
|
||||||
|
_, exports, err := pass.env.GetResolver().loadExports(ctx, c.pkg, includeTest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if pass.env.Debug {
|
if pass.env.Debug {
|
||||||
pass.env.Logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err)
|
pass.env.Logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err)
|
||||||
|
@ -1430,17 +1451,6 @@ func findImport(ctx context.Context, pass *pass, dirScan []*pkg, pkgName string,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadExportsForPackage(ctx context.Context, env *ProcessEnv, expectPkg string, pkg *pkg) ([]string, error) {
|
|
||||||
pkgName, exports, err := env.GetResolver().loadExports(ctx, pkg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if expectPkg != pkgName {
|
|
||||||
return nil, fmt.Errorf("dir %v is package %v, wanted %v", pkg.dir, pkgName, expectPkg)
|
|
||||||
}
|
|
||||||
return exports, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// pkgIsCandidate reports whether pkg is a candidate for satisfying the
|
// pkgIsCandidate reports whether pkg is a candidate for satisfying the
|
||||||
// finding which package pkgIdent in the file named by filename is trying
|
// finding which package pkgIdent in the file named by filename is trying
|
||||||
// to refer to.
|
// to refer to.
|
||||||
|
@ -1453,7 +1463,7 @@ func loadExportsForPackage(ctx context.Context, env *ProcessEnv, expectPkg strin
|
||||||
// filename is the file being formatted.
|
// filename is the file being formatted.
|
||||||
// pkgIdent is the package being searched for, like "client" (if
|
// pkgIdent is the package being searched for, like "client" (if
|
||||||
// searching for "client.New")
|
// searching for "client.New")
|
||||||
func pkgIsCandidate(filename, pkgIdent string, pkg *pkg) bool {
|
func pkgIsCandidate(filename string, refs references, pkg *pkg) bool {
|
||||||
// Check "internal" and "vendor" visibility:
|
// Check "internal" and "vendor" visibility:
|
||||||
if !canUse(filename, pkg.dir) {
|
if !canUse(filename, pkg.dir) {
|
||||||
return false
|
return false
|
||||||
|
@ -1471,17 +1481,18 @@ func pkgIsCandidate(filename, pkgIdent string, pkg *pkg) bool {
|
||||||
// "bar", which is strongly discouraged
|
// "bar", which is strongly discouraged
|
||||||
// anyway. There's no reason goimports needs
|
// anyway. There's no reason goimports needs
|
||||||
// to be slow just to accommodate that.
|
// to be slow just to accommodate that.
|
||||||
lastTwo := lastTwoComponents(pkg.importPathShort)
|
for pkgIdent := range refs {
|
||||||
if strings.Contains(lastTwo, pkgIdent) {
|
lastTwo := lastTwoComponents(pkg.importPathShort)
|
||||||
return true
|
|
||||||
}
|
|
||||||
if hasHyphenOrUpperASCII(lastTwo) && !hasHyphenOrUpperASCII(pkgIdent) {
|
|
||||||
lastTwo = lowerASCIIAndRemoveHyphen(lastTwo)
|
|
||||||
if strings.Contains(lastTwo, pkgIdent) {
|
if strings.Contains(lastTwo, pkgIdent) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if hasHyphenOrUpperASCII(lastTwo) && !hasHyphenOrUpperASCII(pkgIdent) {
|
||||||
|
lastTwo = lowerASCIIAndRemoveHyphen(lastTwo)
|
||||||
|
if strings.Contains(lastTwo, pkgIdent) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
vendor/golang.org/x/tools/internal/imports/imports.go
generated
vendored
52
vendor/golang.org/x/tools/internal/imports/imports.go
generated
vendored
|
@ -11,6 +11,7 @@ package imports
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/build"
|
"go/build"
|
||||||
|
@ -21,6 +22,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -83,42 +85,54 @@ func FixImports(filename string, src []byte, opt *Options) (fixes []*ImportFix,
|
||||||
return getFixes(fileSet, file, filename, opt.Env)
|
return getFixes(fileSet, file, filename, opt.Env)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyFix will apply all of the fixes to the file and format it.
|
// ApplyFixes applies all of the fixes to the file and formats it. extraMode
|
||||||
func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options) (formatted []byte, err error) {
|
// is added in when parsing the file.
|
||||||
|
func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error) {
|
||||||
src, opt, err = initialize(filename, src, opt)
|
src, opt, err = initialize(filename, src, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't use parse() -- we don't care about fragments or statement lists
|
||||||
|
// here, and we need to work with unparseable files.
|
||||||
fileSet := token.NewFileSet()
|
fileSet := token.NewFileSet()
|
||||||
file, adjust, err := parse(fileSet, filename, src, opt)
|
parserMode := parser.Mode(0)
|
||||||
if err != nil {
|
if opt.Comments {
|
||||||
|
parserMode |= parser.ParseComments
|
||||||
|
}
|
||||||
|
if opt.AllErrors {
|
||||||
|
parserMode |= parser.AllErrors
|
||||||
|
}
|
||||||
|
parserMode |= extraMode
|
||||||
|
|
||||||
|
file, err := parser.ParseFile(fileSet, filename, src, parserMode)
|
||||||
|
if file == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the fixes to the file.
|
// Apply the fixes to the file.
|
||||||
apply(fileSet, file, fixes)
|
apply(fileSet, file, fixes)
|
||||||
|
|
||||||
return formatFile(fileSet, file, src, adjust, opt)
|
return formatFile(fileSet, file, src, nil, opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllCandidates gets all of the standard library candidate packages to import in
|
// GetAllCandidates gets all of the packages starting with prefix that can be
|
||||||
// sorted order on import path.
|
// imported by filename, sorted by import path.
|
||||||
func GetAllCandidates(filename string, opt *Options) (pkgs []ImportFix, err error) {
|
func GetAllCandidates(ctx context.Context, callback func(ImportFix), searchPrefix, filename, filePkg string, opt *Options) error {
|
||||||
_, opt, err = initialize(filename, nil, opt)
|
_, opt, err := initialize(filename, []byte{}, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
return getAllCandidates(filename, opt.Env)
|
return getAllCandidates(ctx, callback, searchPrefix, filename, filePkg, opt.Env)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPackageExports returns all known packages with name pkg and their exports.
|
// GetPackageExports returns all known packages with name pkg and their exports.
|
||||||
func GetPackageExports(pkg, filename string, opt *Options) (exports []PackageExport, err error) {
|
func GetPackageExports(ctx context.Context, callback func(PackageExport), searchPkg, filename, filePkg string, opt *Options) error {
|
||||||
_, opt, err = initialize(filename, nil, opt)
|
_, opt, err := initialize(filename, []byte{}, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
return getPackageExports(pkg, filename, opt.Env)
|
return getPackageExports(ctx, callback, searchPkg, filename, filePkg, opt.Env)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize sets the values for opt and src.
|
// initialize sets the values for opt and src.
|
||||||
|
@ -133,8 +147,12 @@ func initialize(filename string, src []byte, opt *Options) ([]byte, *Options, er
|
||||||
// Set the env if the user has not provided it.
|
// Set the env if the user has not provided it.
|
||||||
if opt.Env == nil {
|
if opt.Env == nil {
|
||||||
opt.Env = &ProcessEnv{
|
opt.Env = &ProcessEnv{
|
||||||
GOPATH: build.Default.GOPATH,
|
GOPATH: build.Default.GOPATH,
|
||||||
GOROOT: build.Default.GOROOT,
|
GOROOT: build.Default.GOROOT,
|
||||||
|
GOFLAGS: os.Getenv("GOFLAGS"),
|
||||||
|
GO111MODULE: os.Getenv("GO111MODULE"),
|
||||||
|
GOPROXY: os.Getenv("GOPROXY"),
|
||||||
|
GOSUMDB: os.Getenv("GOSUMDB"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
271
vendor/golang.org/x/tools/internal/imports/mod.go
generated
vendored
271
vendor/golang.org/x/tools/internal/imports/mod.go
generated
vendored
|
@ -13,7 +13,6 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"golang.org/x/tools/internal/gopathwalk"
|
"golang.org/x/tools/internal/gopathwalk"
|
||||||
"golang.org/x/tools/internal/module"
|
"golang.org/x/tools/internal/module"
|
||||||
|
@ -26,11 +25,14 @@ type ModuleResolver struct {
|
||||||
env *ProcessEnv
|
env *ProcessEnv
|
||||||
moduleCacheDir string
|
moduleCacheDir string
|
||||||
dummyVendorMod *ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
|
dummyVendorMod *ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
|
||||||
|
roots []gopathwalk.Root
|
||||||
|
scanSema chan struct{} // scanSema prevents concurrent scans and guards scannedRoots.
|
||||||
|
scannedRoots map[gopathwalk.Root]bool
|
||||||
|
|
||||||
Initialized bool
|
initialized bool
|
||||||
Main *ModuleJSON
|
main *ModuleJSON
|
||||||
ModsByModPath []*ModuleJSON // All modules, ordered by # of path components in module Path...
|
modsByModPath []*ModuleJSON // All modules, ordered by # of path components in module Path...
|
||||||
ModsByDir []*ModuleJSON // ...or Dir.
|
modsByDir []*ModuleJSON // ...or Dir.
|
||||||
|
|
||||||
// moduleCacheCache stores information about the module cache.
|
// moduleCacheCache stores information about the module cache.
|
||||||
moduleCacheCache *dirInfoCache
|
moduleCacheCache *dirInfoCache
|
||||||
|
@ -41,13 +43,23 @@ type ModuleJSON struct {
|
||||||
Path string // module path
|
Path string // module path
|
||||||
Replace *ModuleJSON // replaced by this module
|
Replace *ModuleJSON // replaced by this module
|
||||||
Main bool // is this the main module?
|
Main bool // is this the main module?
|
||||||
|
Indirect bool // is this module only an indirect dependency of main module?
|
||||||
Dir string // directory holding files for this module, if any
|
Dir string // directory holding files for this module, if any
|
||||||
GoMod string // path to go.mod file for this module, if any
|
GoMod string // path to go.mod file for this module, if any
|
||||||
GoVersion string // go version used in module
|
GoVersion string // go version used in module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newModuleResolver(e *ProcessEnv) *ModuleResolver {
|
||||||
|
r := &ModuleResolver{
|
||||||
|
env: e,
|
||||||
|
scanSema: make(chan struct{}, 1),
|
||||||
|
}
|
||||||
|
r.scanSema <- struct{}{}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) init() error {
|
func (r *ModuleResolver) init() error {
|
||||||
if r.Initialized {
|
if r.initialized {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
mainMod, vendorEnabled, err := vendorEnabled(r.env)
|
mainMod, vendorEnabled, err := vendorEnabled(r.env)
|
||||||
|
@ -58,13 +70,13 @@ func (r *ModuleResolver) init() error {
|
||||||
if mainMod != nil && vendorEnabled {
|
if mainMod != nil && vendorEnabled {
|
||||||
// Vendor mode is on, so all the non-Main modules are irrelevant,
|
// Vendor mode is on, so all the non-Main modules are irrelevant,
|
||||||
// and we need to search /vendor for everything.
|
// and we need to search /vendor for everything.
|
||||||
r.Main = mainMod
|
r.main = mainMod
|
||||||
r.dummyVendorMod = &ModuleJSON{
|
r.dummyVendorMod = &ModuleJSON{
|
||||||
Path: "",
|
Path: "",
|
||||||
Dir: filepath.Join(mainMod.Dir, "vendor"),
|
Dir: filepath.Join(mainMod.Dir, "vendor"),
|
||||||
}
|
}
|
||||||
r.ModsByModPath = []*ModuleJSON{mainMod, r.dummyVendorMod}
|
r.modsByModPath = []*ModuleJSON{mainMod, r.dummyVendorMod}
|
||||||
r.ModsByDir = []*ModuleJSON{mainMod, r.dummyVendorMod}
|
r.modsByDir = []*ModuleJSON{mainMod, r.dummyVendorMod}
|
||||||
} else {
|
} else {
|
||||||
// Vendor mode is off, so run go list -m ... to find everything.
|
// Vendor mode is off, so run go list -m ... to find everything.
|
||||||
r.initAllMods()
|
r.initAllMods()
|
||||||
|
@ -72,30 +84,64 @@ func (r *ModuleResolver) init() error {
|
||||||
|
|
||||||
r.moduleCacheDir = filepath.Join(filepath.SplitList(r.env.GOPATH)[0], "/pkg/mod")
|
r.moduleCacheDir = filepath.Join(filepath.SplitList(r.env.GOPATH)[0], "/pkg/mod")
|
||||||
|
|
||||||
sort.Slice(r.ModsByModPath, func(i, j int) bool {
|
sort.Slice(r.modsByModPath, func(i, j int) bool {
|
||||||
count := func(x int) int {
|
count := func(x int) int {
|
||||||
return strings.Count(r.ModsByModPath[x].Path, "/")
|
return strings.Count(r.modsByModPath[x].Path, "/")
|
||||||
}
|
}
|
||||||
return count(j) < count(i) // descending order
|
return count(j) < count(i) // descending order
|
||||||
})
|
})
|
||||||
sort.Slice(r.ModsByDir, func(i, j int) bool {
|
sort.Slice(r.modsByDir, func(i, j int) bool {
|
||||||
count := func(x int) int {
|
count := func(x int) int {
|
||||||
return strings.Count(r.ModsByDir[x].Dir, "/")
|
return strings.Count(r.modsByDir[x].Dir, "/")
|
||||||
}
|
}
|
||||||
return count(j) < count(i) // descending order
|
return count(j) < count(i) // descending order
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.roots = []gopathwalk.Root{
|
||||||
|
{filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT},
|
||||||
|
}
|
||||||
|
if r.main != nil {
|
||||||
|
r.roots = append(r.roots, gopathwalk.Root{r.main.Dir, gopathwalk.RootCurrentModule})
|
||||||
|
}
|
||||||
|
if vendorEnabled {
|
||||||
|
r.roots = append(r.roots, gopathwalk.Root{r.dummyVendorMod.Dir, gopathwalk.RootOther})
|
||||||
|
} else {
|
||||||
|
addDep := func(mod *ModuleJSON) {
|
||||||
|
if mod.Replace == nil {
|
||||||
|
// This is redundant with the cache, but we'll skip it cheaply enough.
|
||||||
|
r.roots = append(r.roots, gopathwalk.Root{mod.Dir, gopathwalk.RootModuleCache})
|
||||||
|
} else {
|
||||||
|
r.roots = append(r.roots, gopathwalk.Root{mod.Dir, gopathwalk.RootOther})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Walk dependent modules before scanning the full mod cache, direct deps first.
|
||||||
|
for _, mod := range r.modsByModPath {
|
||||||
|
if !mod.Indirect && !mod.Main {
|
||||||
|
addDep(mod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, mod := range r.modsByModPath {
|
||||||
|
if mod.Indirect && !mod.Main {
|
||||||
|
addDep(mod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.roots = append(r.roots, gopathwalk.Root{r.moduleCacheDir, gopathwalk.RootModuleCache})
|
||||||
|
}
|
||||||
|
|
||||||
|
r.scannedRoots = map[gopathwalk.Root]bool{}
|
||||||
if r.moduleCacheCache == nil {
|
if r.moduleCacheCache == nil {
|
||||||
r.moduleCacheCache = &dirInfoCache{
|
r.moduleCacheCache = &dirInfoCache{
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
dirs: map[string]*directoryPackageInfo{},
|
||||||
|
listeners: map[*int]cacheListener{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if r.otherCache == nil {
|
if r.otherCache == nil {
|
||||||
r.otherCache = &dirInfoCache{
|
r.otherCache = &dirInfoCache{
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
dirs: map[string]*directoryPackageInfo{},
|
||||||
|
listeners: map[*int]cacheListener{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.Initialized = true
|
r.initialized = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,27 +162,35 @@ func (r *ModuleResolver) initAllMods() error {
|
||||||
// Can't do anything with a module that's not downloaded.
|
// Can't do anything with a module that's not downloaded.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r.ModsByModPath = append(r.ModsByModPath, mod)
|
r.modsByModPath = append(r.modsByModPath, mod)
|
||||||
r.ModsByDir = append(r.ModsByDir, mod)
|
r.modsByDir = append(r.modsByDir, mod)
|
||||||
if mod.Main {
|
if mod.Main {
|
||||||
r.Main = mod
|
r.main = mod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) ClearForNewScan() {
|
func (r *ModuleResolver) ClearForNewScan() {
|
||||||
|
<-r.scanSema
|
||||||
|
r.scannedRoots = map[gopathwalk.Root]bool{}
|
||||||
r.otherCache = &dirInfoCache{
|
r.otherCache = &dirInfoCache{
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
dirs: map[string]*directoryPackageInfo{},
|
||||||
|
listeners: map[*int]cacheListener{},
|
||||||
}
|
}
|
||||||
|
r.scanSema <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) ClearForNewMod() {
|
func (r *ModuleResolver) ClearForNewMod() {
|
||||||
env := r.env
|
<-r.scanSema
|
||||||
*r = ModuleResolver{
|
*r = ModuleResolver{
|
||||||
env: env,
|
env: r.env,
|
||||||
|
moduleCacheCache: r.moduleCacheCache,
|
||||||
|
otherCache: r.otherCache,
|
||||||
|
scanSema: r.scanSema,
|
||||||
}
|
}
|
||||||
r.init()
|
r.init()
|
||||||
|
r.scanSema <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// findPackage returns the module and directory that contains the package at
|
// findPackage returns the module and directory that contains the package at
|
||||||
|
@ -144,7 +198,7 @@ func (r *ModuleResolver) ClearForNewMod() {
|
||||||
func (r *ModuleResolver) findPackage(importPath string) (*ModuleJSON, string) {
|
func (r *ModuleResolver) findPackage(importPath string) (*ModuleJSON, string) {
|
||||||
// This can't find packages in the stdlib, but that's harmless for all
|
// This can't find packages in the stdlib, but that's harmless for all
|
||||||
// the existing code paths.
|
// the existing code paths.
|
||||||
for _, m := range r.ModsByModPath {
|
for _, m := range r.modsByModPath {
|
||||||
if !strings.HasPrefix(importPath, m.Path) {
|
if !strings.HasPrefix(importPath, m.Path) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -211,7 +265,7 @@ func (r *ModuleResolver) cacheKeys() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// cachePackageName caches the package name for a dir already in the cache.
|
// cachePackageName caches the package name for a dir already in the cache.
|
||||||
func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (directoryPackageInfo, error) {
|
func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) {
|
||||||
if info.rootType == gopathwalk.RootModuleCache {
|
if info.rootType == gopathwalk.RootModuleCache {
|
||||||
return r.moduleCacheCache.CachePackageName(info)
|
return r.moduleCacheCache.CachePackageName(info)
|
||||||
}
|
}
|
||||||
|
@ -238,7 +292,7 @@ func (r *ModuleResolver) findModuleByDir(dir string) *ModuleJSON {
|
||||||
// - in /vendor/ in -mod=vendor mode.
|
// - in /vendor/ in -mod=vendor mode.
|
||||||
// - nested module? Dunno.
|
// - nested module? Dunno.
|
||||||
// Rumor has it that replace targets cannot contain other replace targets.
|
// Rumor has it that replace targets cannot contain other replace targets.
|
||||||
for _, m := range r.ModsByDir {
|
for _, m := range r.modsByDir {
|
||||||
if !strings.HasPrefix(dir, m.Dir) {
|
if !strings.HasPrefix(dir, m.Dir) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -333,41 +387,49 @@ func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (
|
||||||
return names, nil
|
return names, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) scan(_ references, loadNames bool, exclude []gopathwalk.RootType) ([]*pkg, error) {
|
func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error {
|
||||||
if err := r.init(); err != nil {
|
if err := r.init(); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk GOROOT, GOPATH/pkg/mod, and the main module.
|
processDir := func(info directoryPackageInfo) {
|
||||||
roots := []gopathwalk.Root{
|
// Skip this directory if we were not able to get the package information successfully.
|
||||||
{filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT},
|
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
||||||
}
|
return
|
||||||
if r.Main != nil {
|
|
||||||
roots = append(roots, gopathwalk.Root{r.Main.Dir, gopathwalk.RootCurrentModule})
|
|
||||||
}
|
|
||||||
if r.dummyVendorMod != nil {
|
|
||||||
roots = append(roots, gopathwalk.Root{r.dummyVendorMod.Dir, gopathwalk.RootOther})
|
|
||||||
} else {
|
|
||||||
roots = append(roots, gopathwalk.Root{r.moduleCacheDir, gopathwalk.RootModuleCache})
|
|
||||||
// Walk replace targets, just in case they're not in any of the above.
|
|
||||||
for _, mod := range r.ModsByModPath {
|
|
||||||
if mod.Replace != nil {
|
|
||||||
roots = append(roots, gopathwalk.Root{mod.Dir, gopathwalk.RootOther})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pkg, err := r.canonicalize(info)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !callback.dirFound(pkg) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pkg.packageName, err = r.cachePackageName(info)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !callback.packageNameLoaded(pkg) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, exports, err := r.loadExports(ctx, pkg, false)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback.exportsLoaded(pkg, exports)
|
||||||
}
|
}
|
||||||
|
|
||||||
roots = filterRoots(roots, exclude)
|
// Start processing everything in the cache, and listen for the new stuff
|
||||||
|
// we discover in the walk below.
|
||||||
|
stop1 := r.moduleCacheCache.ScanAndListen(ctx, processDir)
|
||||||
|
defer stop1()
|
||||||
|
stop2 := r.otherCache.ScanAndListen(ctx, processDir)
|
||||||
|
defer stop2()
|
||||||
|
|
||||||
var result []*pkg
|
// We assume cached directories are fully cached, including all their
|
||||||
var mu sync.Mutex
|
// children, and have not changed. We can skip them.
|
||||||
|
|
||||||
// We assume cached directories have not changed. We can skip them and their
|
|
||||||
// children.
|
|
||||||
skip := func(root gopathwalk.Root, dir string) bool {
|
skip := func(root gopathwalk.Root, dir string) bool {
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
|
|
||||||
info, ok := r.cacheLoad(dir)
|
info, ok := r.cacheLoad(dir)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
|
@ -379,44 +441,64 @@ func (r *ModuleResolver) scan(_ references, loadNames bool, exclude []gopathwalk
|
||||||
return packageScanned
|
return packageScanned
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add anything new to the cache. We'll process everything in it below.
|
// Add anything new to the cache, and process it if we're still listening.
|
||||||
add := func(root gopathwalk.Root, dir string) {
|
add := func(root gopathwalk.Root, dir string) {
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
|
|
||||||
r.cacheStore(r.scanDirForPackage(root, dir))
|
r.cacheStore(r.scanDirForPackage(root, dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
gopathwalk.WalkSkip(roots, add, skip, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
|
// r.roots and the callback are not necessarily safe to use in the
|
||||||
|
// goroutine below. Process them eagerly.
|
||||||
// Everything we already had, and everything new, is now in the cache.
|
roots := filterRoots(r.roots, callback.rootFound)
|
||||||
for _, dir := range r.cacheKeys() {
|
// We can't cancel walks, because we need them to finish to have a usable
|
||||||
info, ok := r.cacheLoad(dir)
|
// cache. Instead, run them in a separate goroutine and detach.
|
||||||
if !ok {
|
scanDone := make(chan struct{})
|
||||||
continue
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-r.scanSema:
|
||||||
}
|
}
|
||||||
|
defer func() { r.scanSema <- struct{}{} }()
|
||||||
|
// We have the lock on r.scannedRoots, and no other scans can run.
|
||||||
|
for _, root := range roots {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Skip this directory if we were not able to get the package information successfully.
|
if r.scannedRoots[root] {
|
||||||
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we want package names, make sure the cache has them.
|
|
||||||
if loadNames {
|
|
||||||
var err error
|
|
||||||
if info, err = r.cachePackageName(info); err != nil {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
|
||||||
|
r.scannedRoots[root] = true
|
||||||
}
|
}
|
||||||
|
close(scanDone)
|
||||||
res, err := r.canonicalize(info)
|
}()
|
||||||
if err != nil {
|
select {
|
||||||
continue
|
case <-ctx.Done():
|
||||||
}
|
case <-scanDone:
|
||||||
result = append(result, res)
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return result, nil
|
func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) int {
|
||||||
|
if _, ok := stdlib[path]; ok {
|
||||||
|
return MaxRelevance
|
||||||
|
}
|
||||||
|
mod, _ := r.findPackage(path)
|
||||||
|
return modRelevance(mod)
|
||||||
|
}
|
||||||
|
|
||||||
|
func modRelevance(mod *ModuleJSON) int {
|
||||||
|
switch {
|
||||||
|
case mod == nil: // out of scope
|
||||||
|
return MaxRelevance - 4
|
||||||
|
case mod.Indirect:
|
||||||
|
return MaxRelevance - 3
|
||||||
|
case !mod.Main:
|
||||||
|
return MaxRelevance - 2
|
||||||
|
default:
|
||||||
|
return MaxRelevance - 1 // main module ties with stdlib
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// canonicalize gets the result of canonicalizing the packages using the results
|
// canonicalize gets the result of canonicalizing the packages using the results
|
||||||
|
@ -428,15 +510,14 @@ func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) {
|
||||||
importPathShort: info.nonCanonicalImportPath,
|
importPathShort: info.nonCanonicalImportPath,
|
||||||
dir: info.dir,
|
dir: info.dir,
|
||||||
packageName: path.Base(info.nonCanonicalImportPath),
|
packageName: path.Base(info.nonCanonicalImportPath),
|
||||||
relevance: 0,
|
relevance: MaxRelevance,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
importPath := info.nonCanonicalImportPath
|
importPath := info.nonCanonicalImportPath
|
||||||
relevance := 2
|
mod := r.findModuleByDir(info.dir)
|
||||||
// Check if the directory is underneath a module that's in scope.
|
// Check if the directory is underneath a module that's in scope.
|
||||||
if mod := r.findModuleByDir(info.dir); mod != nil {
|
if mod != nil {
|
||||||
relevance = 1
|
|
||||||
// It is. If dir is the target of a replace directive,
|
// It is. If dir is the target of a replace directive,
|
||||||
// our guessed import path is wrong. Use the real one.
|
// our guessed import path is wrong. Use the real one.
|
||||||
if mod.Dir == info.dir {
|
if mod.Dir == info.dir {
|
||||||
|
@ -445,15 +526,16 @@ func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) {
|
||||||
dirInMod := info.dir[len(mod.Dir)+len("/"):]
|
dirInMod := info.dir[len(mod.Dir)+len("/"):]
|
||||||
importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod))
|
importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod))
|
||||||
}
|
}
|
||||||
} else if info.needsReplace {
|
} else if !strings.HasPrefix(importPath, info.moduleName) {
|
||||||
|
// The module's name doesn't match the package's import path. It
|
||||||
|
// probably needs a replace directive we don't have.
|
||||||
return nil, fmt.Errorf("package in %q is not valid without a replace statement", info.dir)
|
return nil, fmt.Errorf("package in %q is not valid without a replace statement", info.dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := &pkg{
|
res := &pkg{
|
||||||
importPathShort: importPath,
|
importPathShort: importPath,
|
||||||
dir: info.dir,
|
dir: info.dir,
|
||||||
packageName: info.packageName, // may not be populated if the caller didn't ask for it
|
relevance: modRelevance(mod),
|
||||||
relevance: relevance,
|
|
||||||
}
|
}
|
||||||
// We may have discovered a package that has a different version
|
// We may have discovered a package that has a different version
|
||||||
// in scope already. Canonicalize to that one if possible.
|
// in scope already. Canonicalize to that one if possible.
|
||||||
|
@ -463,14 +545,14 @@ func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg) (string, []string, error) {
|
func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) {
|
||||||
if err := r.init(); err != nil {
|
if err := r.init(); err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
if info, ok := r.cacheLoad(pkg.dir); ok {
|
if info, ok := r.cacheLoad(pkg.dir); ok && !includeTest {
|
||||||
return r.cacheExports(ctx, r.env, info)
|
return r.cacheExports(ctx, r.env, info)
|
||||||
}
|
}
|
||||||
return loadExportsFromFiles(ctx, r.env, pkg.dir)
|
return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) directoryPackageInfo {
|
func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) directoryPackageInfo {
|
||||||
|
@ -488,7 +570,7 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) dir
|
||||||
}
|
}
|
||||||
switch root.Type {
|
switch root.Type {
|
||||||
case gopathwalk.RootCurrentModule:
|
case gopathwalk.RootCurrentModule:
|
||||||
importPath = path.Join(r.Main.Path, filepath.ToSlash(subdir))
|
importPath = path.Join(r.main.Path, filepath.ToSlash(subdir))
|
||||||
case gopathwalk.RootModuleCache:
|
case gopathwalk.RootModuleCache:
|
||||||
matches := modCacheRegexp.FindStringSubmatch(subdir)
|
matches := modCacheRegexp.FindStringSubmatch(subdir)
|
||||||
if len(matches) == 0 {
|
if len(matches) == 0 {
|
||||||
|
@ -516,7 +598,6 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) dir
|
||||||
dir: dir,
|
dir: dir,
|
||||||
rootType: root.Type,
|
rootType: root.Type,
|
||||||
nonCanonicalImportPath: importPath,
|
nonCanonicalImportPath: importPath,
|
||||||
needsReplace: false,
|
|
||||||
moduleDir: modDir,
|
moduleDir: modDir,
|
||||||
moduleName: modName,
|
moduleName: modName,
|
||||||
}
|
}
|
||||||
|
@ -524,14 +605,6 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) dir
|
||||||
// stdlib packages are always in scope, despite the confusing go.mod
|
// stdlib packages are always in scope, despite the confusing go.mod
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
// Check that this package is not obviously impossible to import.
|
|
||||||
if !strings.HasPrefix(importPath, modName) {
|
|
||||||
// The module's declared path does not match
|
|
||||||
// its expected path. It probably needs a
|
|
||||||
// replace directive we don't have.
|
|
||||||
result.needsReplace = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
94
vendor/golang.org/x/tools/internal/imports/mod_cache.go
generated
vendored
94
vendor/golang.org/x/tools/internal/imports/mod_cache.go
generated
vendored
|
@ -49,10 +49,6 @@ type directoryPackageInfo struct {
|
||||||
// nonCanonicalImportPath is the package's expected import path. It may
|
// nonCanonicalImportPath is the package's expected import path. It may
|
||||||
// not actually be importable at that path.
|
// not actually be importable at that path.
|
||||||
nonCanonicalImportPath string
|
nonCanonicalImportPath string
|
||||||
// needsReplace is true if the nonCanonicalImportPath does not match the
|
|
||||||
// module's declared path, making it impossible to import without a
|
|
||||||
// replace directive.
|
|
||||||
needsReplace bool
|
|
||||||
|
|
||||||
// Module-related information.
|
// Module-related information.
|
||||||
moduleDir string // The directory that is the module root of this dir.
|
moduleDir string // The directory that is the module root of this dir.
|
||||||
|
@ -97,15 +93,85 @@ func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (
|
||||||
type dirInfoCache struct {
|
type dirInfoCache struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
// dirs stores information about packages in directories, keyed by absolute path.
|
// dirs stores information about packages in directories, keyed by absolute path.
|
||||||
dirs map[string]*directoryPackageInfo
|
dirs map[string]*directoryPackageInfo
|
||||||
|
listeners map[*int]cacheListener
|
||||||
|
}
|
||||||
|
|
||||||
|
type cacheListener func(directoryPackageInfo)
|
||||||
|
|
||||||
|
// ScanAndListen calls listener on all the items in the cache, and on anything
|
||||||
|
// newly added. The returned stop function waits for all in-flight callbacks to
|
||||||
|
// finish and blocks new ones.
|
||||||
|
func (d *dirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() {
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
|
// Flushing out all the callbacks is tricky without knowing how many there
|
||||||
|
// are going to be. Setting an arbitrary limit makes it much easier.
|
||||||
|
const maxInFlight = 10
|
||||||
|
sema := make(chan struct{}, maxInFlight)
|
||||||
|
for i := 0; i < maxInFlight; i++ {
|
||||||
|
sema <- struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie := new(int) // A unique ID we can use for the listener.
|
||||||
|
|
||||||
|
// We can't hold mu while calling the listener.
|
||||||
|
d.mu.Lock()
|
||||||
|
var keys []string
|
||||||
|
for key := range d.dirs {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
d.listeners[cookie] = func(info directoryPackageInfo) {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-sema:
|
||||||
|
}
|
||||||
|
listener(info)
|
||||||
|
sema <- struct{}{}
|
||||||
|
}
|
||||||
|
d.mu.Unlock()
|
||||||
|
|
||||||
|
// Process the pre-existing keys.
|
||||||
|
for _, k := range keys {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
cancel()
|
||||||
|
return func() {}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
if v, ok := d.Load(k); ok {
|
||||||
|
listener(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
cancel()
|
||||||
|
d.mu.Lock()
|
||||||
|
delete(d.listeners, cookie)
|
||||||
|
d.mu.Unlock()
|
||||||
|
for i := 0; i < maxInFlight; i++ {
|
||||||
|
<-sema
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store stores the package info for dir.
|
// Store stores the package info for dir.
|
||||||
func (d *dirInfoCache) Store(dir string, info directoryPackageInfo) {
|
func (d *dirInfoCache) Store(dir string, info directoryPackageInfo) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
_, old := d.dirs[dir]
|
||||||
stored := info // defensive copy
|
d.dirs[dir] = &info
|
||||||
d.dirs[dir] = &stored
|
var listeners []cacheListener
|
||||||
|
for _, l := range d.listeners {
|
||||||
|
listeners = append(listeners, l)
|
||||||
|
}
|
||||||
|
d.mu.Unlock()
|
||||||
|
|
||||||
|
if !old {
|
||||||
|
for _, l := range listeners {
|
||||||
|
l(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load returns a copy of the directoryPackageInfo for absolute directory dir.
|
// Load returns a copy of the directoryPackageInfo for absolute directory dir.
|
||||||
|
@ -129,17 +195,17 @@ func (d *dirInfoCache) Keys() (keys []string) {
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (directoryPackageInfo, error) {
|
func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) {
|
||||||
if loaded, err := info.reachedStatus(nameLoaded); loaded {
|
if loaded, err := info.reachedStatus(nameLoaded); loaded {
|
||||||
return info, err
|
return info.packageName, err
|
||||||
}
|
}
|
||||||
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
||||||
return info, fmt.Errorf("cannot read package name, scan error: %v", err)
|
return "", fmt.Errorf("cannot read package name, scan error: %v", err)
|
||||||
}
|
}
|
||||||
info.packageName, info.err = packageDirToName(info.dir)
|
info.packageName, info.err = packageDirToName(info.dir)
|
||||||
info.status = nameLoaded
|
info.status = nameLoaded
|
||||||
d.Store(info.dir, info)
|
d.Store(info.dir, info)
|
||||||
return info, info.err
|
return info.packageName, info.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) {
|
func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) {
|
||||||
|
@ -149,8 +215,8 @@ func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info d
|
||||||
if reached, err := info.reachedStatus(nameLoaded); reached && err != nil {
|
if reached, err := info.reachedStatus(nameLoaded); reached && err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
info.packageName, info.exports, info.err = loadExportsFromFiles(ctx, env, info.dir)
|
info.packageName, info.exports, info.err = loadExportsFromFiles(ctx, env, info.dir, false)
|
||||||
if info.err == context.Canceled {
|
if info.err == context.Canceled || info.err == context.DeadlineExceeded {
|
||||||
return info.packageName, info.exports, info.err
|
return info.packageName, info.exports, info.err
|
||||||
}
|
}
|
||||||
// The cache structure wants things to proceed linearly. We can skip a
|
// The cache structure wants things to proceed linearly. We can skip a
|
||||||
|
|
4
vendor/golang.org/x/tools/internal/packagesinternal/packages.go
generated
vendored
Normal file
4
vendor/golang.org/x/tools/internal/packagesinternal/packages.go
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// Package packagesinternal exposes internal-only fields from go/packages.
|
||||||
|
package packagesinternal
|
||||||
|
|
||||||
|
var GetForTest = func(p interface{}) string { return "" }
|
100
vendor/golang.org/x/tools/internal/span/parse.go
generated
vendored
100
vendor/golang.org/x/tools/internal/span/parse.go
generated
vendored
|
@ -1,100 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parse returns the location represented by the input.
|
|
||||||
// All inputs are valid locations, as they can always be a pure filename.
|
|
||||||
// The returned span will be normalized, and thus if printed may produce a
|
|
||||||
// different string.
|
|
||||||
func Parse(input string) Span {
|
|
||||||
// :0:0#0-0:0#0
|
|
||||||
valid := input
|
|
||||||
var hold, offset int
|
|
||||||
hadCol := false
|
|
||||||
suf := rstripSuffix(input)
|
|
||||||
if suf.sep == "#" {
|
|
||||||
offset = suf.num
|
|
||||||
suf = rstripSuffix(suf.remains)
|
|
||||||
}
|
|
||||||
if suf.sep == ":" {
|
|
||||||
valid = suf.remains
|
|
||||||
hold = suf.num
|
|
||||||
hadCol = true
|
|
||||||
suf = rstripSuffix(suf.remains)
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case suf.sep == ":":
|
|
||||||
return New(NewURI(suf.remains), NewPoint(suf.num, hold, offset), Point{})
|
|
||||||
case suf.sep == "-":
|
|
||||||
// we have a span, fall out of the case to continue
|
|
||||||
default:
|
|
||||||
// separator not valid, rewind to either the : or the start
|
|
||||||
return New(NewURI(valid), NewPoint(hold, 0, offset), Point{})
|
|
||||||
}
|
|
||||||
// only the span form can get here
|
|
||||||
// at this point we still don't know what the numbers we have mean
|
|
||||||
// if have not yet seen a : then we might have either a line or a column depending
|
|
||||||
// on whether start has a column or not
|
|
||||||
// we build an end point and will fix it later if needed
|
|
||||||
end := NewPoint(suf.num, hold, offset)
|
|
||||||
hold, offset = 0, 0
|
|
||||||
suf = rstripSuffix(suf.remains)
|
|
||||||
if suf.sep == "#" {
|
|
||||||
offset = suf.num
|
|
||||||
suf = rstripSuffix(suf.remains)
|
|
||||||
}
|
|
||||||
if suf.sep != ":" {
|
|
||||||
// turns out we don't have a span after all, rewind
|
|
||||||
return New(NewURI(valid), end, Point{})
|
|
||||||
}
|
|
||||||
valid = suf.remains
|
|
||||||
hold = suf.num
|
|
||||||
suf = rstripSuffix(suf.remains)
|
|
||||||
if suf.sep != ":" {
|
|
||||||
// line#offset only
|
|
||||||
return New(NewURI(valid), NewPoint(hold, 0, offset), end)
|
|
||||||
}
|
|
||||||
// we have a column, so if end only had one number, it is also the column
|
|
||||||
if !hadCol {
|
|
||||||
end = NewPoint(suf.num, end.v.Line, end.v.Offset)
|
|
||||||
}
|
|
||||||
return New(NewURI(suf.remains), NewPoint(suf.num, hold, offset), end)
|
|
||||||
}
|
|
||||||
|
|
||||||
type suffix struct {
|
|
||||||
remains string
|
|
||||||
sep string
|
|
||||||
num int
|
|
||||||
}
|
|
||||||
|
|
||||||
func rstripSuffix(input string) suffix {
|
|
||||||
if len(input) == 0 {
|
|
||||||
return suffix{"", "", -1}
|
|
||||||
}
|
|
||||||
remains := input
|
|
||||||
num := -1
|
|
||||||
// first see if we have a number at the end
|
|
||||||
last := strings.LastIndexFunc(remains, func(r rune) bool { return r < '0' || r > '9' })
|
|
||||||
if last >= 0 && last < len(remains)-1 {
|
|
||||||
number, err := strconv.ParseInt(remains[last+1:], 10, 64)
|
|
||||||
if err == nil {
|
|
||||||
num = int(number)
|
|
||||||
remains = remains[:last+1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now see if we have a trailing separator
|
|
||||||
r, w := utf8.DecodeLastRuneInString(remains)
|
|
||||||
if r != ':' && r != '#' && r == '#' {
|
|
||||||
return suffix{input, "", -1}
|
|
||||||
}
|
|
||||||
remains = remains[:len(remains)-w]
|
|
||||||
return suffix{remains, string(r), num}
|
|
||||||
}
|
|
285
vendor/golang.org/x/tools/internal/span/span.go
generated
vendored
285
vendor/golang.org/x/tools/internal/span/span.go
generated
vendored
|
@ -1,285 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package span contains support for representing with positions and ranges in
|
|
||||||
// text files.
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"path"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Span represents a source code range in standardized form.
|
|
||||||
type Span struct {
|
|
||||||
v span
|
|
||||||
}
|
|
||||||
|
|
||||||
// Point represents a single point within a file.
|
|
||||||
// In general this should only be used as part of a Span, as on its own it
|
|
||||||
// does not carry enough information.
|
|
||||||
type Point struct {
|
|
||||||
v point
|
|
||||||
}
|
|
||||||
|
|
||||||
type span struct {
|
|
||||||
URI URI `json:"uri"`
|
|
||||||
Start point `json:"start"`
|
|
||||||
End point `json:"end"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type point struct {
|
|
||||||
Line int `json:"line"`
|
|
||||||
Column int `json:"column"`
|
|
||||||
Offset int `json:"offset"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalid is a span that reports false from IsValid
|
|
||||||
var Invalid = Span{v: span{Start: invalidPoint.v, End: invalidPoint.v}}
|
|
||||||
|
|
||||||
var invalidPoint = Point{v: point{Line: 0, Column: 0, Offset: -1}}
|
|
||||||
|
|
||||||
// Converter is the interface to an object that can convert between line:column
|
|
||||||
// and offset forms for a single file.
|
|
||||||
type Converter interface {
|
|
||||||
//ToPosition converts from an offset to a line:column pair.
|
|
||||||
ToPosition(offset int) (int, int, error)
|
|
||||||
//ToOffset converts from a line:column pair to an offset.
|
|
||||||
ToOffset(line, col int) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(uri URI, start Point, end Point) Span {
|
|
||||||
s := Span{v: span{URI: uri, Start: start.v, End: end.v}}
|
|
||||||
s.v.clean()
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPoint(line, col, offset int) Point {
|
|
||||||
p := Point{v: point{Line: line, Column: col, Offset: offset}}
|
|
||||||
p.v.clean()
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func Compare(a, b Span) int {
|
|
||||||
if r := CompareURI(a.URI(), b.URI()); r != 0 {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
if r := comparePoint(a.v.Start, b.v.Start); r != 0 {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
return comparePoint(a.v.End, b.v.End)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComparePoint(a, b Point) int {
|
|
||||||
return comparePoint(a.v, b.v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func comparePoint(a, b point) int {
|
|
||||||
if !a.hasPosition() {
|
|
||||||
if a.Offset < b.Offset {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if a.Offset > b.Offset {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if a.Line < b.Line {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if a.Line > b.Line {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if a.Column < b.Column {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if a.Column > b.Column {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Span) HasPosition() bool { return s.v.Start.hasPosition() }
|
|
||||||
func (s Span) HasOffset() bool { return s.v.Start.hasOffset() }
|
|
||||||
func (s Span) IsValid() bool { return s.v.Start.isValid() }
|
|
||||||
func (s Span) IsPoint() bool { return s.v.Start == s.v.End }
|
|
||||||
func (s Span) URI() URI { return s.v.URI }
|
|
||||||
func (s Span) Start() Point { return Point{s.v.Start} }
|
|
||||||
func (s Span) End() Point { return Point{s.v.End} }
|
|
||||||
func (s *Span) MarshalJSON() ([]byte, error) { return json.Marshal(&s.v) }
|
|
||||||
func (s *Span) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &s.v) }
|
|
||||||
|
|
||||||
func (p Point) HasPosition() bool { return p.v.hasPosition() }
|
|
||||||
func (p Point) HasOffset() bool { return p.v.hasOffset() }
|
|
||||||
func (p Point) IsValid() bool { return p.v.isValid() }
|
|
||||||
func (p *Point) MarshalJSON() ([]byte, error) { return json.Marshal(&p.v) }
|
|
||||||
func (p *Point) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &p.v) }
|
|
||||||
func (p Point) Line() int {
|
|
||||||
if !p.v.hasPosition() {
|
|
||||||
panic(fmt.Errorf("position not set in %v", p.v))
|
|
||||||
}
|
|
||||||
return p.v.Line
|
|
||||||
}
|
|
||||||
func (p Point) Column() int {
|
|
||||||
if !p.v.hasPosition() {
|
|
||||||
panic(fmt.Errorf("position not set in %v", p.v))
|
|
||||||
}
|
|
||||||
return p.v.Column
|
|
||||||
}
|
|
||||||
func (p Point) Offset() int {
|
|
||||||
if !p.v.hasOffset() {
|
|
||||||
panic(fmt.Errorf("offset not set in %v", p.v))
|
|
||||||
}
|
|
||||||
return p.v.Offset
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p point) hasPosition() bool { return p.Line > 0 }
|
|
||||||
func (p point) hasOffset() bool { return p.Offset >= 0 }
|
|
||||||
func (p point) isValid() bool { return p.hasPosition() || p.hasOffset() }
|
|
||||||
func (p point) isZero() bool {
|
|
||||||
return (p.Line == 1 && p.Column == 1) || (!p.hasPosition() && p.Offset == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *span) clean() {
|
|
||||||
//this presumes the points are already clean
|
|
||||||
if !s.End.isValid() || (s.End == point{}) {
|
|
||||||
s.End = s.Start
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *point) clean() {
|
|
||||||
if p.Line < 0 {
|
|
||||||
p.Line = 0
|
|
||||||
}
|
|
||||||
if p.Column <= 0 {
|
|
||||||
if p.Line > 0 {
|
|
||||||
p.Column = 1
|
|
||||||
} else {
|
|
||||||
p.Column = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.Offset == 0 && (p.Line > 1 || p.Column > 1) {
|
|
||||||
p.Offset = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format implements fmt.Formatter to print the Location in a standard form.
|
|
||||||
// The format produced is one that can be read back in using Parse.
|
|
||||||
func (s Span) Format(f fmt.State, c rune) {
|
|
||||||
fullForm := f.Flag('+')
|
|
||||||
preferOffset := f.Flag('#')
|
|
||||||
// we should always have a uri, simplify if it is file format
|
|
||||||
//TODO: make sure the end of the uri is unambiguous
|
|
||||||
uri := string(s.v.URI)
|
|
||||||
if c == 'f' {
|
|
||||||
uri = path.Base(uri)
|
|
||||||
} else if !fullForm {
|
|
||||||
uri = s.v.URI.Filename()
|
|
||||||
}
|
|
||||||
fmt.Fprint(f, uri)
|
|
||||||
if !s.IsValid() || (!fullForm && s.v.Start.isZero() && s.v.End.isZero()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// see which bits of start to write
|
|
||||||
printOffset := s.HasOffset() && (fullForm || preferOffset || !s.HasPosition())
|
|
||||||
printLine := s.HasPosition() && (fullForm || !printOffset)
|
|
||||||
printColumn := printLine && (fullForm || (s.v.Start.Column > 1 || s.v.End.Column > 1))
|
|
||||||
fmt.Fprint(f, ":")
|
|
||||||
if printLine {
|
|
||||||
fmt.Fprintf(f, "%d", s.v.Start.Line)
|
|
||||||
}
|
|
||||||
if printColumn {
|
|
||||||
fmt.Fprintf(f, ":%d", s.v.Start.Column)
|
|
||||||
}
|
|
||||||
if printOffset {
|
|
||||||
fmt.Fprintf(f, "#%d", s.v.Start.Offset)
|
|
||||||
}
|
|
||||||
// start is written, do we need end?
|
|
||||||
if s.IsPoint() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// we don't print the line if it did not change
|
|
||||||
printLine = fullForm || (printLine && s.v.End.Line > s.v.Start.Line)
|
|
||||||
fmt.Fprint(f, "-")
|
|
||||||
if printLine {
|
|
||||||
fmt.Fprintf(f, "%d", s.v.End.Line)
|
|
||||||
}
|
|
||||||
if printColumn {
|
|
||||||
if printLine {
|
|
||||||
fmt.Fprint(f, ":")
|
|
||||||
}
|
|
||||||
fmt.Fprintf(f, "%d", s.v.End.Column)
|
|
||||||
}
|
|
||||||
if printOffset {
|
|
||||||
fmt.Fprintf(f, "#%d", s.v.End.Offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Span) WithPosition(c Converter) (Span, error) {
|
|
||||||
if err := s.update(c, true, false); err != nil {
|
|
||||||
return Span{}, err
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Span) WithOffset(c Converter) (Span, error) {
|
|
||||||
if err := s.update(c, false, true); err != nil {
|
|
||||||
return Span{}, err
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Span) WithAll(c Converter) (Span, error) {
|
|
||||||
if err := s.update(c, true, true); err != nil {
|
|
||||||
return Span{}, err
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Span) update(c Converter, withPos, withOffset bool) error {
|
|
||||||
if !s.IsValid() {
|
|
||||||
return fmt.Errorf("cannot add information to an invalid span")
|
|
||||||
}
|
|
||||||
if withPos && !s.HasPosition() {
|
|
||||||
if err := s.v.Start.updatePosition(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if s.v.End.Offset == s.v.Start.Offset {
|
|
||||||
s.v.End = s.v.Start
|
|
||||||
} else if err := s.v.End.updatePosition(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if withOffset && (!s.HasOffset() || (s.v.End.hasPosition() && !s.v.End.hasOffset())) {
|
|
||||||
if err := s.v.Start.updateOffset(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if s.v.End.Line == s.v.Start.Line && s.v.End.Column == s.v.Start.Column {
|
|
||||||
s.v.End.Offset = s.v.Start.Offset
|
|
||||||
} else if err := s.v.End.updateOffset(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *point) updatePosition(c Converter) error {
|
|
||||||
line, col, err := c.ToPosition(p.Offset)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.Line = line
|
|
||||||
p.Column = col
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *point) updateOffset(c Converter) error {
|
|
||||||
offset, err := c.ToOffset(p.Line, p.Column)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.Offset = offset
|
|
||||||
return nil
|
|
||||||
}
|
|
179
vendor/golang.org/x/tools/internal/span/token.go
generated
vendored
179
vendor/golang.org/x/tools/internal/span/token.go
generated
vendored
|
@ -1,179 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"go/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Range represents a source code range in token.Pos form.
|
|
||||||
// It also carries the FileSet that produced the positions, so that it is
|
|
||||||
// self contained.
|
|
||||||
type Range struct {
|
|
||||||
FileSet *token.FileSet
|
|
||||||
Start token.Pos
|
|
||||||
End token.Pos
|
|
||||||
Converter Converter
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenConverter is a Converter backed by a token file set and file.
|
|
||||||
// It uses the file set methods to work out the conversions, which
|
|
||||||
// makes it fast and does not require the file contents.
|
|
||||||
type TokenConverter struct {
|
|
||||||
fset *token.FileSet
|
|
||||||
file *token.File
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRange creates a new Range from a FileSet and two positions.
|
|
||||||
// To represent a point pass a 0 as the end pos.
|
|
||||||
func NewRange(fset *token.FileSet, start, end token.Pos) Range {
|
|
||||||
return Range{
|
|
||||||
FileSet: fset,
|
|
||||||
Start: start,
|
|
||||||
End: end,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTokenConverter returns an implementation of Converter backed by a
|
|
||||||
// token.File.
|
|
||||||
func NewTokenConverter(fset *token.FileSet, f *token.File) *TokenConverter {
|
|
||||||
return &TokenConverter{fset: fset, file: f}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewContentConverter returns an implementation of Converter for the
|
|
||||||
// given file content.
|
|
||||||
func NewContentConverter(filename string, content []byte) *TokenConverter {
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
f := fset.AddFile(filename, -1, len(content))
|
|
||||||
f.SetLinesForContent(content)
|
|
||||||
return &TokenConverter{fset: fset, file: f}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsPoint returns true if the range represents a single point.
|
|
||||||
func (r Range) IsPoint() bool {
|
|
||||||
return r.Start == r.End
|
|
||||||
}
|
|
||||||
|
|
||||||
// Span converts a Range to a Span that represents the Range.
|
|
||||||
// It will fill in all the members of the Span, calculating the line and column
|
|
||||||
// information.
|
|
||||||
func (r Range) Span() (Span, error) {
|
|
||||||
f := r.FileSet.File(r.Start)
|
|
||||||
if f == nil {
|
|
||||||
return Span{}, fmt.Errorf("file not found in FileSet")
|
|
||||||
}
|
|
||||||
var s Span
|
|
||||||
var err error
|
|
||||||
var startFilename string
|
|
||||||
startFilename, s.v.Start.Line, s.v.Start.Column, err = position(f, r.Start)
|
|
||||||
if err != nil {
|
|
||||||
return Span{}, err
|
|
||||||
}
|
|
||||||
s.v.URI = FileURI(startFilename)
|
|
||||||
if r.End.IsValid() {
|
|
||||||
var endFilename string
|
|
||||||
endFilename, s.v.End.Line, s.v.End.Column, err = position(f, r.End)
|
|
||||||
if err != nil {
|
|
||||||
return Span{}, err
|
|
||||||
}
|
|
||||||
// In the presence of line directives, a single File can have sections from
|
|
||||||
// multiple file names.
|
|
||||||
if endFilename != startFilename {
|
|
||||||
return Span{}, fmt.Errorf("span begins in file %q but ends in %q", startFilename, endFilename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.v.Start.clean()
|
|
||||||
s.v.End.clean()
|
|
||||||
s.v.clean()
|
|
||||||
if r.Converter != nil {
|
|
||||||
return s.WithOffset(r.Converter)
|
|
||||||
}
|
|
||||||
if startFilename != f.Name() {
|
|
||||||
return Span{}, fmt.Errorf("must supply Converter for file %q containing lines from %q", f.Name(), startFilename)
|
|
||||||
}
|
|
||||||
return s.WithOffset(NewTokenConverter(r.FileSet, f))
|
|
||||||
}
|
|
||||||
|
|
||||||
func position(f *token.File, pos token.Pos) (string, int, int, error) {
|
|
||||||
off, err := offset(f, pos)
|
|
||||||
if err != nil {
|
|
||||||
return "", 0, 0, err
|
|
||||||
}
|
|
||||||
return positionFromOffset(f, off)
|
|
||||||
}
|
|
||||||
|
|
||||||
func positionFromOffset(f *token.File, offset int) (string, int, int, error) {
|
|
||||||
if offset > f.Size() {
|
|
||||||
return "", 0, 0, fmt.Errorf("offset %v is past the end of the file %v", offset, f.Size())
|
|
||||||
}
|
|
||||||
pos := f.Pos(offset)
|
|
||||||
p := f.Position(pos)
|
|
||||||
if offset == f.Size() {
|
|
||||||
return p.Filename, p.Line + 1, 1, nil
|
|
||||||
}
|
|
||||||
return p.Filename, p.Line, p.Column, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// offset is a copy of the Offset function in go/token, but with the adjustment
|
|
||||||
// that it does not panic on invalid positions.
|
|
||||||
func offset(f *token.File, pos token.Pos) (int, error) {
|
|
||||||
if int(pos) < f.Base() || int(pos) > f.Base()+f.Size() {
|
|
||||||
return 0, fmt.Errorf("invalid pos")
|
|
||||||
}
|
|
||||||
return int(pos) - f.Base(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range converts a Span to a Range that represents the Span for the supplied
|
|
||||||
// File.
|
|
||||||
func (s Span) Range(converter *TokenConverter) (Range, error) {
|
|
||||||
s, err := s.WithOffset(converter)
|
|
||||||
if err != nil {
|
|
||||||
return Range{}, err
|
|
||||||
}
|
|
||||||
// go/token will panic if the offset is larger than the file's size,
|
|
||||||
// so check here to avoid panicking.
|
|
||||||
if s.Start().Offset() > converter.file.Size() {
|
|
||||||
return Range{}, fmt.Errorf("start offset %v is past the end of the file %v", s.Start(), converter.file.Size())
|
|
||||||
}
|
|
||||||
if s.End().Offset() > converter.file.Size() {
|
|
||||||
return Range{}, fmt.Errorf("end offset %v is past the end of the file %v", s.End(), converter.file.Size())
|
|
||||||
}
|
|
||||||
return Range{
|
|
||||||
FileSet: converter.fset,
|
|
||||||
Start: converter.file.Pos(s.Start().Offset()),
|
|
||||||
End: converter.file.Pos(s.End().Offset()),
|
|
||||||
Converter: converter,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *TokenConverter) ToPosition(offset int) (int, int, error) {
|
|
||||||
_, line, col, err := positionFromOffset(l.file, offset)
|
|
||||||
return line, col, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *TokenConverter) ToOffset(line, col int) (int, error) {
|
|
||||||
if line < 0 {
|
|
||||||
return -1, fmt.Errorf("line is not valid")
|
|
||||||
}
|
|
||||||
lineMax := l.file.LineCount() + 1
|
|
||||||
if line > lineMax {
|
|
||||||
return -1, fmt.Errorf("line is beyond end of file %v", lineMax)
|
|
||||||
} else if line == lineMax {
|
|
||||||
if col > 1 {
|
|
||||||
return -1, fmt.Errorf("column is beyond end of file")
|
|
||||||
}
|
|
||||||
// at the end of the file, allowing for a trailing eol
|
|
||||||
return l.file.Size(), nil
|
|
||||||
}
|
|
||||||
pos := lineStart(l.file, line)
|
|
||||||
if !pos.IsValid() {
|
|
||||||
return -1, fmt.Errorf("line is not in file")
|
|
||||||
}
|
|
||||||
// we assume that column is in bytes here, and that the first byte of a
|
|
||||||
// line is at column 1
|
|
||||||
pos += token.Pos(col - 1)
|
|
||||||
return offset(l.file, pos)
|
|
||||||
}
|
|
39
vendor/golang.org/x/tools/internal/span/token111.go
generated
vendored
39
vendor/golang.org/x/tools/internal/span/token111.go
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !go1.12
|
|
||||||
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
// lineStart is the pre-Go 1.12 version of (*token.File).LineStart. For Go
|
|
||||||
// versions <= 1.11, we borrow logic from the analysisutil package.
|
|
||||||
// TODO(rstambler): Delete this file when we no longer support Go 1.11.
|
|
||||||
func lineStart(f *token.File, line int) token.Pos {
|
|
||||||
// Use binary search to find the start offset of this line.
|
|
||||||
|
|
||||||
min := 0 // inclusive
|
|
||||||
max := f.Size() // exclusive
|
|
||||||
for {
|
|
||||||
offset := (min + max) / 2
|
|
||||||
pos := f.Pos(offset)
|
|
||||||
posn := f.Position(pos)
|
|
||||||
if posn.Line == line {
|
|
||||||
return pos - (token.Pos(posn.Column) - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if min+1 >= max {
|
|
||||||
return token.NoPos
|
|
||||||
}
|
|
||||||
|
|
||||||
if posn.Line < line {
|
|
||||||
min = offset
|
|
||||||
} else {
|
|
||||||
max = offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
16
vendor/golang.org/x/tools/internal/span/token112.go
generated
vendored
16
vendor/golang.org/x/tools/internal/span/token112.go
generated
vendored
|
@ -1,16 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.12
|
|
||||||
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(rstambler): Delete this file when we no longer support Go 1.11.
|
|
||||||
func lineStart(f *token.File, line int) token.Pos {
|
|
||||||
return f.LineStart(line)
|
|
||||||
}
|
|
152
vendor/golang.org/x/tools/internal/span/uri.go
generated
vendored
152
vendor/golang.org/x/tools/internal/span/uri.go
generated
vendored
|
@ -1,152 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileScheme = "file"
|
|
||||||
|
|
||||||
// URI represents the full URI for a file.
|
|
||||||
type URI string
|
|
||||||
|
|
||||||
// Filename returns the file path for the given URI.
|
|
||||||
// It is an error to call this on a URI that is not a valid filename.
|
|
||||||
func (uri URI) Filename() string {
|
|
||||||
filename, err := filename(uri)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return filepath.FromSlash(filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func filename(uri URI) (string, error) {
|
|
||||||
if uri == "" {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
u, err := url.ParseRequestURI(string(uri))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if u.Scheme != fileScheme {
|
|
||||||
return "", fmt.Errorf("only file URIs are supported, got %q from %q", u.Scheme, uri)
|
|
||||||
}
|
|
||||||
if isWindowsDriveURI(u.Path) {
|
|
||||||
u.Path = u.Path[1:]
|
|
||||||
}
|
|
||||||
return u.Path, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewURI returns a span URI for the string.
|
|
||||||
// It will attempt to detect if the string is a file path or uri.
|
|
||||||
func NewURI(s string) URI {
|
|
||||||
if u, err := url.PathUnescape(s); err == nil {
|
|
||||||
s = u
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(s, fileScheme+"://") {
|
|
||||||
return URI(s)
|
|
||||||
}
|
|
||||||
return FileURI(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CompareURI(a, b URI) int {
|
|
||||||
if equalURI(a, b) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if a < b {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func equalURI(a, b URI) bool {
|
|
||||||
if a == b {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// If we have the same URI basename, we may still have the same file URIs.
|
|
||||||
if !strings.EqualFold(path.Base(string(a)), path.Base(string(b))) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fa, err := filename(a)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fb, err := filename(b)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// Stat the files to check if they are equal.
|
|
||||||
infoa, err := os.Stat(filepath.FromSlash(fa))
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
infob, err := os.Stat(filepath.FromSlash(fb))
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return os.SameFile(infoa, infob)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileURI returns a span URI for the supplied file path.
|
|
||||||
// It will always have the file scheme.
|
|
||||||
func FileURI(path string) URI {
|
|
||||||
if path == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
// Handle standard library paths that contain the literal "$GOROOT".
|
|
||||||
// TODO(rstambler): The go/packages API should allow one to determine a user's $GOROOT.
|
|
||||||
const prefix = "$GOROOT"
|
|
||||||
if len(path) >= len(prefix) && strings.EqualFold(prefix, path[:len(prefix)]) {
|
|
||||||
suffix := path[len(prefix):]
|
|
||||||
path = runtime.GOROOT() + suffix
|
|
||||||
}
|
|
||||||
if !isWindowsDrivePath(path) {
|
|
||||||
if abs, err := filepath.Abs(path); err == nil {
|
|
||||||
path = abs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check the file path again, in case it became absolute.
|
|
||||||
if isWindowsDrivePath(path) {
|
|
||||||
path = "/" + path
|
|
||||||
}
|
|
||||||
path = filepath.ToSlash(path)
|
|
||||||
u := url.URL{
|
|
||||||
Scheme: fileScheme,
|
|
||||||
Path: path,
|
|
||||||
}
|
|
||||||
uri := u.String()
|
|
||||||
if unescaped, err := url.PathUnescape(uri); err == nil {
|
|
||||||
uri = unescaped
|
|
||||||
}
|
|
||||||
return URI(uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
// isWindowsDrivePath returns true if the file path is of the form used by
|
|
||||||
// Windows. We check if the path begins with a drive letter, followed by a ":".
|
|
||||||
func isWindowsDrivePath(path string) bool {
|
|
||||||
if len(path) < 4 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return unicode.IsLetter(rune(path[0])) && path[1] == ':'
|
|
||||||
}
|
|
||||||
|
|
||||||
// isWindowsDriveURI returns true if the file URI is of the format used by
|
|
||||||
// Windows URIs. The url.Parse package does not specially handle Windows paths
|
|
||||||
// (see https://golang.org/issue/6027). We check if the URI path has
|
|
||||||
// a drive prefix (e.g. "/C:"). If so, we trim the leading "/".
|
|
||||||
func isWindowsDriveURI(uri string) bool {
|
|
||||||
if len(uri) < 4 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':'
|
|
||||||
}
|
|
94
vendor/golang.org/x/tools/internal/span/utf16.go
generated
vendored
94
vendor/golang.org/x/tools/internal/span/utf16.go
generated
vendored
|
@ -1,94 +0,0 @@
|
||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package span
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"unicode/utf16"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToUTF16Column calculates the utf16 column expressed by the point given the
|
|
||||||
// supplied file contents.
|
|
||||||
// This is used to convert from the native (always in bytes) column
|
|
||||||
// representation and the utf16 counts used by some editors.
|
|
||||||
func ToUTF16Column(p Point, content []byte) (int, error) {
|
|
||||||
if content == nil {
|
|
||||||
return -1, fmt.Errorf("ToUTF16Column: missing content")
|
|
||||||
}
|
|
||||||
if !p.HasPosition() {
|
|
||||||
return -1, fmt.Errorf("ToUTF16Column: point is missing position")
|
|
||||||
}
|
|
||||||
if !p.HasOffset() {
|
|
||||||
return -1, fmt.Errorf("ToUTF16Column: point is missing offset")
|
|
||||||
}
|
|
||||||
offset := p.Offset() // 0-based
|
|
||||||
colZero := p.Column() - 1 // 0-based
|
|
||||||
if colZero == 0 {
|
|
||||||
// 0-based column 0, so it must be chr 1
|
|
||||||
return 1, nil
|
|
||||||
} else if colZero < 0 {
|
|
||||||
return -1, fmt.Errorf("ToUTF16Column: column is invalid (%v)", colZero)
|
|
||||||
}
|
|
||||||
// work out the offset at the start of the line using the column
|
|
||||||
lineOffset := offset - colZero
|
|
||||||
if lineOffset < 0 || offset > len(content) {
|
|
||||||
return -1, fmt.Errorf("ToUTF16Column: offsets %v-%v outside file contents (%v)", lineOffset, offset, len(content))
|
|
||||||
}
|
|
||||||
// Use the offset to pick out the line start.
|
|
||||||
// This cannot panic: offset > len(content) and lineOffset < offset.
|
|
||||||
start := content[lineOffset:]
|
|
||||||
|
|
||||||
// Now, truncate down to the supplied column.
|
|
||||||
start = start[:colZero]
|
|
||||||
|
|
||||||
// and count the number of utf16 characters
|
|
||||||
// in theory we could do this by hand more efficiently...
|
|
||||||
return len(utf16.Encode([]rune(string(start)))) + 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromUTF16Column advances the point by the utf16 character offset given the
|
|
||||||
// supplied line contents.
|
|
||||||
// This is used to convert from the utf16 counts used by some editors to the
|
|
||||||
// native (always in bytes) column representation.
|
|
||||||
func FromUTF16Column(p Point, chr int, content []byte) (Point, error) {
|
|
||||||
if !p.HasOffset() {
|
|
||||||
return Point{}, fmt.Errorf("FromUTF16Column: point is missing offset")
|
|
||||||
}
|
|
||||||
// if chr is 1 then no adjustment needed
|
|
||||||
if chr <= 1 {
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
if p.Offset() >= len(content) {
|
|
||||||
return p, fmt.Errorf("FromUTF16Column: offset (%v) greater than length of content (%v)", p.Offset(), len(content))
|
|
||||||
}
|
|
||||||
remains := content[p.Offset():]
|
|
||||||
// scan forward the specified number of characters
|
|
||||||
for count := 1; count < chr; count++ {
|
|
||||||
if len(remains) <= 0 {
|
|
||||||
return Point{}, fmt.Errorf("FromUTF16Column: chr goes beyond the content")
|
|
||||||
}
|
|
||||||
r, w := utf8.DecodeRune(remains)
|
|
||||||
if r == '\n' {
|
|
||||||
// Per the LSP spec:
|
|
||||||
//
|
|
||||||
// > If the character value is greater than the line length it
|
|
||||||
// > defaults back to the line length.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
remains = remains[w:]
|
|
||||||
if r >= 0x10000 {
|
|
||||||
// a two point rune
|
|
||||||
count++
|
|
||||||
// if we finished in a two point rune, do not advance past the first
|
|
||||||
if count >= chr {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.v.Column += w
|
|
||||||
p.v.Offset += w
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
2
vendor/gopkg.in/testfixtures.v2/go.mod
generated
vendored
2
vendor/gopkg.in/testfixtures.v2/go.mod
generated
vendored
|
@ -13,3 +13,5 @@ require (
|
||||||
google.golang.org/appengine v1.3.0 // indirect
|
google.golang.org/appengine v1.3.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
47
vendor/gopkg.in/yaml.v2/scannerc.go
generated
vendored
47
vendor/gopkg.in/yaml.v2/scannerc.go
generated
vendored
|
@ -626,32 +626,18 @@ func trace(args ...interface{}) func() {
|
||||||
func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
|
func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
|
||||||
// While we need more tokens to fetch, do it.
|
// While we need more tokens to fetch, do it.
|
||||||
for {
|
for {
|
||||||
// Check if we really need to fetch more tokens.
|
if parser.tokens_head != len(parser.tokens) {
|
||||||
need_more_tokens := false
|
// If queue is non-empty, check if any potential simple key may
|
||||||
|
// occupy the head position.
|
||||||
if parser.tokens_head == len(parser.tokens) {
|
head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed]
|
||||||
// Queue is empty.
|
if !ok {
|
||||||
need_more_tokens = true
|
break
|
||||||
} else {
|
} else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok {
|
||||||
// Check if any potential simple key may occupy the head position.
|
return false
|
||||||
for i := len(parser.simple_keys) - 1; i >= 0; i-- {
|
} else if !valid {
|
||||||
simple_key := &parser.simple_keys[i]
|
break
|
||||||
if simple_key.token_number < parser.tokens_parsed {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok {
|
|
||||||
return false
|
|
||||||
} else if valid && simple_key.token_number == parser.tokens_parsed {
|
|
||||||
need_more_tokens = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are finished.
|
|
||||||
if !need_more_tokens {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Fetch the next token.
|
// Fetch the next token.
|
||||||
if !yaml_parser_fetch_next_token(parser) {
|
if !yaml_parser_fetch_next_token(parser) {
|
||||||
return false
|
return false
|
||||||
|
@ -883,6 +869,7 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
parser.simple_keys[len(parser.simple_keys)-1] = simple_key
|
parser.simple_keys[len(parser.simple_keys)-1] = simple_key
|
||||||
|
parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -897,9 +884,10 @@ func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
|
||||||
"while scanning a simple key", parser.simple_keys[i].mark,
|
"while scanning a simple key", parser.simple_keys[i].mark,
|
||||||
"could not find expected ':'")
|
"could not find expected ':'")
|
||||||
}
|
}
|
||||||
|
// Remove the key from the stack.
|
||||||
|
parser.simple_keys[i].possible = false
|
||||||
|
delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number)
|
||||||
}
|
}
|
||||||
// Remove the key from the stack.
|
|
||||||
parser.simple_keys[i].possible = false
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,7 +918,9 @@ func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
|
||||||
func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
|
func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
|
||||||
if parser.flow_level > 0 {
|
if parser.flow_level > 0 {
|
||||||
parser.flow_level--
|
parser.flow_level--
|
||||||
parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
|
last := len(parser.simple_keys) - 1
|
||||||
|
delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number)
|
||||||
|
parser.simple_keys = parser.simple_keys[:last]
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1007,6 +997,8 @@ func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
|
||||||
// Initialize the simple key stack.
|
// Initialize the simple key stack.
|
||||||
parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
|
parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
|
||||||
|
|
||||||
|
parser.simple_keys_by_tok = make(map[int]int)
|
||||||
|
|
||||||
// A simple key is allowed at the beginning of the stream.
|
// A simple key is allowed at the beginning of the stream.
|
||||||
parser.simple_key_allowed = true
|
parser.simple_key_allowed = true
|
||||||
|
|
||||||
|
@ -1310,6 +1302,7 @@ func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
|
||||||
|
|
||||||
// Remove the simple key.
|
// Remove the simple key.
|
||||||
simple_key.possible = false
|
simple_key.possible = false
|
||||||
|
delete(parser.simple_keys_by_tok, simple_key.token_number)
|
||||||
|
|
||||||
// A simple key cannot follow another simple key.
|
// A simple key cannot follow another simple key.
|
||||||
parser.simple_key_allowed = false
|
parser.simple_key_allowed = false
|
||||||
|
|
1
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
1
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
|
@ -579,6 +579,7 @@ type yaml_parser_t struct {
|
||||||
|
|
||||||
simple_key_allowed bool // May a simple key occur at the current position?
|
simple_key_allowed bool // May a simple key occur at the current position?
|
||||||
simple_keys []yaml_simple_key_t // The stack of simple keys.
|
simple_keys []yaml_simple_key_t // The stack of simple keys.
|
||||||
|
simple_keys_by_tok map[int]int // possible simple_key indexes indexed by token_number
|
||||||
|
|
||||||
// Parser stuff
|
// Parser stuff
|
||||||
|
|
||||||
|
|
12
vendor/modules.txt
vendored
12
vendor/modules.txt
vendored
|
@ -50,9 +50,9 @@ github.com/ghodss/yaml
|
||||||
github.com/go-openapi/jsonpointer
|
github.com/go-openapi/jsonpointer
|
||||||
# github.com/go-openapi/jsonreference v0.19.3
|
# github.com/go-openapi/jsonreference v0.19.3
|
||||||
github.com/go-openapi/jsonreference
|
github.com/go-openapi/jsonreference
|
||||||
# github.com/go-openapi/spec v0.19.4
|
# github.com/go-openapi/spec v0.19.5
|
||||||
github.com/go-openapi/spec
|
github.com/go-openapi/spec
|
||||||
# github.com/go-openapi/swag v0.19.5
|
# github.com/go-openapi/swag v0.19.7
|
||||||
github.com/go-openapi/swag
|
github.com/go-openapi/swag
|
||||||
# github.com/go-redis/redis v6.15.2+incompatible
|
# github.com/go-redis/redis v6.15.2+incompatible
|
||||||
github.com/go-redis/redis
|
github.com/go-redis/redis
|
||||||
|
@ -184,7 +184,7 @@ github.com/spf13/pflag
|
||||||
github.com/spf13/viper
|
github.com/spf13/viper
|
||||||
# github.com/stretchr/testify v1.4.0
|
# github.com/stretchr/testify v1.4.0
|
||||||
github.com/stretchr/testify/assert
|
github.com/stretchr/testify/assert
|
||||||
# github.com/swaggo/swag v1.6.3
|
# github.com/swaggo/swag v1.6.5
|
||||||
github.com/swaggo/swag
|
github.com/swaggo/swag
|
||||||
github.com/swaggo/swag/cmd/swag
|
github.com/swaggo/swag/cmd/swag
|
||||||
github.com/swaggo/swag/gen
|
github.com/swaggo/swag/gen
|
||||||
|
@ -217,7 +217,7 @@ golang.org/x/text/transform
|
||||||
golang.org/x/text/unicode/bidi
|
golang.org/x/text/unicode/bidi
|
||||||
golang.org/x/text/unicode/norm
|
golang.org/x/text/unicode/norm
|
||||||
golang.org/x/text/width
|
golang.org/x/text/width
|
||||||
# golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d
|
# golang.org/x/tools v0.0.0-20200125223703-d33eef8e6825
|
||||||
golang.org/x/tools/go/ast/astutil
|
golang.org/x/tools/go/ast/astutil
|
||||||
golang.org/x/tools/go/ast/inspector
|
golang.org/x/tools/go/ast/inspector
|
||||||
golang.org/x/tools/go/buildutil
|
golang.org/x/tools/go/buildutil
|
||||||
|
@ -233,8 +233,8 @@ golang.org/x/tools/internal/fastwalk
|
||||||
golang.org/x/tools/internal/gopathwalk
|
golang.org/x/tools/internal/gopathwalk
|
||||||
golang.org/x/tools/internal/imports
|
golang.org/x/tools/internal/imports
|
||||||
golang.org/x/tools/internal/module
|
golang.org/x/tools/internal/module
|
||||||
|
golang.org/x/tools/internal/packagesinternal
|
||||||
golang.org/x/tools/internal/semver
|
golang.org/x/tools/internal/semver
|
||||||
golang.org/x/tools/internal/span
|
|
||||||
# google.golang.org/appengine v1.5.0
|
# google.golang.org/appengine v1.5.0
|
||||||
google.golang.org/appengine/cloudsql
|
google.golang.org/appengine/cloudsql
|
||||||
# gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
|
# gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
|
||||||
|
@ -245,7 +245,7 @@ gopkg.in/d4l3k/messagediff.v1
|
||||||
gopkg.in/gomail.v2
|
gopkg.in/gomail.v2
|
||||||
# gopkg.in/testfixtures.v2 v2.5.3
|
# gopkg.in/testfixtures.v2 v2.5.3
|
||||||
gopkg.in/testfixtures.v2
|
gopkg.in/testfixtures.v2
|
||||||
# gopkg.in/yaml.v2 v2.2.7
|
# gopkg.in/yaml.v2 v2.2.8
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
# honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a
|
# honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a
|
||||||
honnef.co/go/tools/arg
|
honnef.co/go/tools/arg
|
||||||
|
|
Loading…
Reference in New Issue
Block a user