зеркало из https://github.com/golang/pkgsite.git
internal/fetch: implement fetch and insert version to postgres
An initial version FetchAndInsertVersion is implemented, which: (1) Downloads the given module version from the module proxy (2) Process the contents: - Calculate series name - Get the contents of the README - Get the contents of the license - Get packages for the module (3) Writes the data to postgres. Change-Id: Iabce23879124a03599dc5779302e69cc5e432f88 Reviewed-on: https://team-review.git.corp.google.com/c/422995 Reviewed-by: Andrew Bonventre <andybons@google.com>
This commit is contained in:
Родитель
b8bb5b03f7
Коммит
79ac5ae337
2
go.mod
2
go.mod
|
@ -3,5 +3,5 @@ module golang.org/x/discovery
|
|||
require (
|
||||
github.com/lib/pq v1.0.0
|
||||
gocloud.dev v0.10.0
|
||||
golang.org/x/tools v0.0.0-20190220190617-97f80cd5504d
|
||||
golang.org/x/tools v0.0.0-20181221154417-3ad2d988d5e2
|
||||
)
|
||||
|
|
41
go.sum
41
go.sum
|
@ -41,12 +41,14 @@ github.com/SAP/go-hdb v0.13.1/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCn
|
|||
github.com/SAP/go-hdb v0.13.2/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0=
|
||||
github.com/SermoDigital/jose v0.9.1/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
|
||||
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190122153857-e0ace9b64d22/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20181031164735-a56c009257a7/go.mod h1:GjvccvtI06FGFvRU1In/maF7tKp3h7GBV9Sexo5rNPM=
|
||||
|
@ -114,9 +116,11 @@ github.com/duosecurity/duo_api_golang v0.0.0-20181024123116-92fea9203dbc/go.mod
|
|||
github.com/duosecurity/duo_api_golang v0.0.0-20190107154727-539434bf0d45/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo=
|
||||
github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
@ -126,6 +130,7 @@ github.com/gammazero/workerpool v0.0.0-20181230203049-86a96b5d5d92/go.mod h1:w9R
|
|||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/getkin/kin-openapi v0.1.0/go.mod h1:+0ZtELZf+SlWH8ZdA/IeFb3L/PKOKJx8eGxAlUZ/sOU=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
|
@ -139,6 +144,7 @@ github.com/go-stomp/stomp v2.0.2+incompatible/go.mod h1:VqCtqNZv1226A1/79yh+rMiF
|
|||
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gocql/gocql v0.0.0-20181117210152-33c0e89ca93a/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/gocql/gocql v0.0.0-20190122205811-30de9a1866a8/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/gddo v0.0.0-20181116215533-9bd4a3295021/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
|
@ -152,11 +158,15 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
|
|||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
|
@ -175,10 +185,13 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
|||
github.com/goreleaser/goreleaser v0.94.0/go.mod h1:OjbYR2NhOI6AEUWCowMSBzo9nP1aRif3sYtx+rhp+Zo=
|
||||
github.com/goreleaser/nfpm v0.9.7/go.mod h1:F2yzin6cBAL9gb+mSiReuXdsfTrOQwDMsuSpULof+y4=
|
||||
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
|
@ -234,6 +247,7 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe
|
|||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
|
||||
github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/flux v0.13.0/go.mod h1:81jeDcHVn1rN5uj9aQ81S72Q8ol8If7N0zM0G8TnxTE=
|
||||
|
@ -243,6 +257,7 @@ github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1
|
|||
github.com/influxdata/platform v0.0.0-20190117200541-d500d3cf5589/go.mod h1:YVhys+JOY4wmXtJvdtkzLhS2K/r/px/vPc+EAddK+pg=
|
||||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2/go.mod h1:xkfESuHriIekR+4RoV+fu91j/CfnYM29Zi2tMFw5iD4=
|
||||
github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM=
|
||||
|
@ -253,6 +268,7 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i
|
|||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jsternberg/zap-logfmt v1.2.0/go.mod h1:kz+1CUmCutPWABnNkOu9hOHKdT2q3TDYCcsFy9hpqb0=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
|
@ -260,6 +276,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
|||
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||
github.com/kevinburke/go-bindata v3.11.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/keybase/go-crypto v0.0.0-20181031135447-f919bfda4fc1/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||
github.com/keybase/go-crypto v0.0.0-20181127160227-255a5089e85a/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||
|
@ -288,6 +305,7 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v
|
|||
github.com/miekg/dns v1.1.1/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
|
@ -297,6 +315,7 @@ github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
|
|||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mna/pigeon v1.0.1-0.20180808201053-bb0192cfc2ae/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04=
|
||||
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/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
|
@ -322,11 +341,13 @@ github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnh
|
|||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
|
||||
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -346,9 +367,11 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
|
|||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
|
@ -386,8 +409,10 @@ github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgK
|
|||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
|
||||
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
||||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50/go.mod h1:1pdIZTAHUz+HDKDVZ++5xg/duPlhKAIzw9qy42CWYp4=
|
||||
github.com/streadway/amqp v0.0.0-20181205114330-a314942b2fd9/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
|
||||
|
@ -408,6 +433,7 @@ github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW
|
|||
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181012064053-8333dd449516/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro=
|
||||
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
|
@ -431,6 +457,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
|
|||
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190122013713-64072686203f h1:u1CmMhe3a44hy8VIgpInORnI01UVaUYheqR7x9BxT3c=
|
||||
golang.org/x/crypto v0.0.0-20190122013713-64072686203f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20181112044915-a3060d491354/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -448,8 +475,6 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190119204137-ed066c81e75e h1:MDa3fSUp6MdYHouVmCCNz/zaH2a6CRcxY3VhT/K3C5Q=
|
||||
golang.org/x/net v0.0.0-20190119204137-ed066c81e75e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/oauth2 v0.0.0-20180603041954-1e0a3fa8ba9a/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
@ -476,6 +501,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -483,8 +509,6 @@ golang.org/x/tools v0.0.0-20181017214349-06f26fdaaa28/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181221154417-3ad2d988d5e2 h1:M7NLB69gFpUH4s6SJLwXiVs45aZfVjqGKynfNFKSGcI=
|
||||
golang.org/x/tools v0.0.0-20181221154417-3ad2d988d5e2/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190220190617-97f80cd5504d h1:c7LLuMAYgBPaDC7+tYrCSMtjTYFZRQOtDBnVJ5sV79w=
|
||||
golang.org/x/tools v0.0.0-20190220190617-97f80cd5504d/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/xerrors v0.0.0-20190129162528-20feca13ea86 h1:kMgZCSynBSIN3PHpvuFeMExQwPWtUZ/xfnt2Yr2cp20=
|
||||
golang.org/x/xerrors v0.0.0-20190129162528-20feca13ea86/go.mod h1:/lyp46tcDBI65C0XC8F4d0/XVb7MT7RScVRech7dX/4=
|
||||
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
|
@ -526,6 +550,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/fatih/pool.v2 v2.0.0/go.mod h1:8xVGeu1/2jr2wm5V9SPuMht2H5AEmf5aFMGSQixtjTY=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gorethink/gorethink.v4 v4.1.0/go.mod h1:M7JgwrUAmshJ3iUbEK0Pt049MPyPK+CYDGGaEjdZb/c=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
|
@ -533,11 +558,15 @@ gopkg.in/ory-am/dockertest.v2 v2.2.3/go.mod h1:kDHEsan1UcKFYH1c28sDmqnmeqIpB4Nj6
|
|||
gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544/go.mod h1:UhTeH/yXCK/KY7TX24mqPkaQ7gZeqmWd/8SSS8B3aHw=
|
||||
gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5/go.mod h1:hiOFpYm0ZJbusNj2ywpbrXowU3G8U6GIQzqn2mw1UIE=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo=
|
||||
gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||
gopkg.in/src-d/go-git.v4 v4.8.1 h1:aAyBmkdE1QUUEHcP4YFCGKmsMQRAuRmUcPEQR7lOAa0=
|
||||
gopkg.in/src-d/go-git.v4 v4.8.1/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/vmihailenco/msgpack.v2 v2.9.1/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -546,12 +575,16 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
|
|||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20181108184350-ae8f1f9103cc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.0.0-20181221193117-173ce66c1e39 h1:iGq7zEPXFb0IeXAQK5RiYT1SVKX/af9F9Wv0M+yudPY=
|
||||
k8s.io/api v0.0.0-20181221193117-173ce66c1e39/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apimachinery v0.0.0-20190119020841-d41becfba9ee h1:3MH/wGFP+9PjyLIMnPN2GYatdJosd+5TnSO2BzQqqo4=
|
||||
k8s.io/apimachinery v0.0.0-20190119020841-d41becfba9ee/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/klog v0.1.0 h1:I5HMfc/DtuVaGR1KPwUrTc476K8NCqNBldC7H4dYEzk=
|
||||
k8s.io/klog v0.1.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
layeh.com/radius v0.0.0-20190118135028-0f678f039617/go.mod h1:fywZKyu//X7iRzaxLgPWsvc0L26IUpVvE/aeIL2JtIQ=
|
||||
pack.ag/amqp v0.8.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
|
||||
pack.ag/amqp v0.10.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
|
|
|
@ -16,10 +16,14 @@ import (
|
|||
"strings"
|
||||
|
||||
"golang.org/x/discovery/internal"
|
||||
"golang.org/x/discovery/internal/postgres"
|
||||
"golang.org/x/discovery/internal/proxy"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
var errReadmeNotFound = errors.New("fetch: zip file does not contain a README")
|
||||
var (
|
||||
errModuleContainsNoPackages = errors.New("module contains 0 packages")
|
||||
)
|
||||
|
||||
// ParseNameAndVersion returns the module and version specified by u. u is
|
||||
// assumed to be a valid url following the structure http(s)://<fetchURL>/<module>@<version>.
|
||||
|
@ -40,50 +44,72 @@ func ParseNameAndVersion(u *url.URL) (string, string, error) {
|
|||
return parts[0], parts[1], nil
|
||||
}
|
||||
|
||||
// isReadme checks if file is the README. It is case insensitive.
|
||||
func isReadme(file string) bool {
|
||||
base := filepath.Base(file)
|
||||
f := strings.TrimSuffix(base, filepath.Ext(base))
|
||||
return strings.ToUpper(f) == "README"
|
||||
}
|
||||
|
||||
// containsReadme checks if rc contains a README file.
|
||||
func containsReadme(rc *zip.ReadCloser) bool {
|
||||
for _, zipFile := range rc.File {
|
||||
if isReadme(zipFile.Name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// readReadme reads the contents of the first file from rc that passes the
|
||||
// isReadme check. It returns an error if such a file does not exist.
|
||||
func readReadme(rc *zip.ReadCloser) ([]byte, error) {
|
||||
for _, zipFile := range rc.File {
|
||||
if isReadme(zipFile.Name) {
|
||||
return readZipFile(zipFile)
|
||||
}
|
||||
}
|
||||
return nil, errReadmeNotFound
|
||||
}
|
||||
|
||||
// readZipFile returns the uncompressed contents of f or an error if the
|
||||
// uncompressed size of f exceeds 1MB.
|
||||
func readZipFile(f *zip.File) ([]byte, error) {
|
||||
if f.UncompressedSize64 > 1e6 {
|
||||
return nil, fmt.Errorf("file size %d exceeds 1MB, skipping", f.UncompressedSize64)
|
||||
}
|
||||
rc, err := f.Open()
|
||||
// FetchAndInsertVersion downloads the given module version from the module proxy, processes
|
||||
// the contents, and writes the data to the database. The fetch service will:
|
||||
// (1) Get the version commit time from the proxy
|
||||
// (2) Download the version zip from the proxy
|
||||
// (3) Process the contents (series name, readme, license, and packages)
|
||||
// (4) Write the data to the discovery database
|
||||
func FetchAndInsertVersion(name, version string, proxyClient *proxy.Client, db *postgres.DB) error {
|
||||
info, err := proxyClient.GetInfo(name, version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return fmt.Errorf("proxyClient.GetInfo(%q, %q): %v", name, version, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
return ioutil.ReadAll(rc)
|
||||
|
||||
zipReader, err := proxyClient.GetZip(name, version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proxyClient.GetZip(%q, %q): %v", name, version, err)
|
||||
}
|
||||
|
||||
var readme []byte
|
||||
readmeFile := "README"
|
||||
if containsFile(zipReader, readmeFile) {
|
||||
readme, err = extractFile(zipReader, readmeFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("extractFile(%v, %q): %v", zipReader, readmeFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
var license []byte
|
||||
licenseFile := "LICENSE"
|
||||
if containsFile(zipReader, licenseFile) {
|
||||
license, err = extractFile(zipReader, licenseFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("extractFile(%v, %q): %v", zipReader, licenseFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
seriesName, err := seriesNameForModule(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("seriesNameForModule(%q): %v", name, err)
|
||||
}
|
||||
|
||||
packages, err := extractPackagesFromZip(name, version, zipReader)
|
||||
if err != nil && err != errModuleContainsNoPackages {
|
||||
return fmt.Errorf("extractPackagesFromZip(%q, %q, %v): %v", name, version, zipReader, err)
|
||||
}
|
||||
|
||||
v := internal.Version{
|
||||
Module: &internal.Module{
|
||||
Name: name,
|
||||
Series: &internal.Series{
|
||||
Name: seriesName,
|
||||
},
|
||||
},
|
||||
Version: version,
|
||||
CommitTime: info.Time,
|
||||
ReadMe: string(readme),
|
||||
License: string(license),
|
||||
Packages: packages,
|
||||
}
|
||||
if err = db.InsertVersion(&v); err != nil {
|
||||
return fmt.Errorf("db.InsertVersion(%+v): %v", v, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractPackagesFromZip returns a slice of packages from the module zip r.
|
||||
func extractPackagesFromZip(module string, r *zip.ReadCloser) ([]*internal.Package, error) {
|
||||
func extractPackagesFromZip(module, version string, r *zip.Reader) ([]*internal.Package, error) {
|
||||
// Create a temporary directory to write the contents of the module zip.
|
||||
tempPrefix := "discovery_"
|
||||
dir, err := ioutil.TempDir("", tempPrefix)
|
||||
|
@ -121,7 +147,7 @@ func extractPackagesFromZip(module string, r *zip.ReadCloser) ([]*internal.Packa
|
|||
|
||||
config := &packages.Config{
|
||||
Mode: packages.LoadSyntax,
|
||||
Dir: fmt.Sprintf("%s/%s", dir, module),
|
||||
Dir: fmt.Sprintf("%s/%s@%s", dir, module, version),
|
||||
}
|
||||
pattern := fmt.Sprintf("%s/...", module)
|
||||
pkgs, err := packages.Load(config, pattern)
|
||||
|
@ -130,7 +156,7 @@ func extractPackagesFromZip(module string, r *zip.ReadCloser) ([]*internal.Packa
|
|||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
return nil, fmt.Errorf("packages.Load(%+v, %q) returned 0 packages", config, pattern)
|
||||
return nil, errModuleContainsNoPackages
|
||||
}
|
||||
|
||||
packages := []*internal.Package{}
|
||||
|
@ -174,3 +200,51 @@ func seriesNameForModule(name string) (string, error) {
|
|||
}
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// extractFile reads the contents of the first file from r that passes the
|
||||
// hasFilename check for expectedFile. It returns an error if such a file
|
||||
// does not exist.
|
||||
func extractFile(r *zip.Reader, expectedFile string) ([]byte, error) {
|
||||
for _, zipFile := range r.File {
|
||||
if hasFilename(zipFile.Name, expectedFile) {
|
||||
c, err := readZipFile(zipFile)
|
||||
return c, err
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("zip does not contain %q", expectedFile)
|
||||
}
|
||||
|
||||
// containsFile checks if r contains expectedFile.
|
||||
func containsFile(r *zip.Reader, expectedFile string) bool {
|
||||
for _, zipFile := range r.File {
|
||||
if hasFilename(zipFile.Name, expectedFile) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// hasFilename checks if:
|
||||
// (1) file is expectedFile, or
|
||||
// (2) the name of file, without the base, is equal to expectedFile.
|
||||
// It is case insensitive.
|
||||
func hasFilename(file string, expectedFile string) bool {
|
||||
base := filepath.Base(file)
|
||||
return strings.EqualFold(base, expectedFile) ||
|
||||
strings.EqualFold(strings.TrimSuffix(base, filepath.Ext(base)), expectedFile)
|
||||
}
|
||||
|
||||
// readZipFile returns the uncompressed contents of f or an error if the
|
||||
// uncompressed size of f exceeds 1MB.
|
||||
func readZipFile(f *zip.File) ([]byte, error) {
|
||||
if f.UncompressedSize64 > 1e6 {
|
||||
return nil, fmt.Errorf("file size %d exceeds 1MB, skipping", f.UncompressedSize64)
|
||||
}
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
b, err := ioutil.ReadAll(rc)
|
||||
return b, err
|
||||
}
|
||||
|
|
|
@ -8,12 +8,91 @@ import (
|
|||
"archive/zip"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/discovery/internal"
|
||||
"golang.org/x/discovery/internal/postgres"
|
||||
"golang.org/x/discovery/internal/proxy"
|
||||
)
|
||||
|
||||
// structToString returns a string containing the fields and values of a given
|
||||
// struct i. It is used in error messages for tests.
|
||||
func structToString(i interface{}) string {
|
||||
s := reflect.ValueOf(i).Elem()
|
||||
typeOfT := s.Type()
|
||||
|
||||
var b strings.Builder
|
||||
for i := 0; i < s.NumField(); i++ {
|
||||
f := s.Field(i)
|
||||
fmt.Fprintf(&b, fmt.Sprintf("%d: %s %s = %v \n", i, typeOfT.Field(i).Name, f.Type(), f.Interface()))
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func TestFetchAndInsertVersion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
version string
|
||||
versionData *internal.Version
|
||||
}{
|
||||
{
|
||||
name: "my/module",
|
||||
version: "v1.0.0",
|
||||
versionData: &internal.Version{
|
||||
Module: &internal.Module{
|
||||
Name: "my/module",
|
||||
},
|
||||
Version: "v1.0.0",
|
||||
CommitTime: time.Date(2019, 1, 30, 0, 0, 0, 0, time.UTC),
|
||||
ReadMe: "README FILE FOR TESTING.",
|
||||
License: "LICENSE FILE FOR TESTING.",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
teardownDB, db := postgres.SetupCleanDB(t)
|
||||
defer teardownDB(t)
|
||||
|
||||
teardownProxyClient, client := proxy.SetupTestProxyClient(t)
|
||||
defer teardownProxyClient(t)
|
||||
|
||||
if err := FetchAndInsertVersion(tc.name, tc.version, client, db); err != nil {
|
||||
t.Fatalf("FetchVersion(%q, %q, %v, %v): %v", tc.name, tc.version, client, db, err)
|
||||
}
|
||||
|
||||
got, err := db.GetVersion(tc.name, tc.version)
|
||||
if err != nil {
|
||||
t.Fatalf("db.GetVersion(%q, %q): %v", tc.name, tc.version, err)
|
||||
}
|
||||
|
||||
// Set CreatedAt and UpdatedAt to nil for testing, since these are
|
||||
// set by the database.
|
||||
got.CreatedAt = time.Time{}
|
||||
got.UpdatedAt = time.Time{}
|
||||
|
||||
// got.CommitTime has a timezone location of +0000, while
|
||||
// tc.versionData.CommitTime has a timezone location of UTC.
|
||||
// These are equal according to time.Equal, but fail for
|
||||
// reflect.DeepEqual. Convert the DB time to UTC.
|
||||
got.CommitTime = got.CommitTime.UTC()
|
||||
|
||||
if !reflect.DeepEqual(*got, *tc.versionData) {
|
||||
t.Errorf("db.GetVersion(%q, %q): \n %s \n want: \n %s",
|
||||
tc.name, tc.version, structToString(got), structToString(tc.versionData))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseNameAndVersion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -75,89 +154,58 @@ func TestParseNameAndVersion(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIsReadme(t *testing.T) {
|
||||
for input, want := range map[string]bool{
|
||||
"rEaDme": true,
|
||||
"README.FOO": true,
|
||||
"FOO_README": false,
|
||||
"README_FOO": false,
|
||||
"README.FOO.FOO": false,
|
||||
func TestHasFilename(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
file string
|
||||
expectedFile string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
file: "my/module@v1.0.0/README.md",
|
||||
expectedFile: "README.md",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
file: "rEaDme",
|
||||
expectedFile: "README",
|
||||
want: true,
|
||||
}, {
|
||||
file: "README.FOO",
|
||||
expectedFile: "README",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
file: "FOO_README",
|
||||
expectedFile: "README",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
file: "README_FOO",
|
||||
expectedFile: "README",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
file: "README.FOO.FOO",
|
||||
expectedFile: "README",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
file: "",
|
||||
expectedFile: "README",
|
||||
want: false,
|
||||
},
|
||||
} {
|
||||
got := isReadme(input)
|
||||
if got != want {
|
||||
t.Errorf("isReadme(%q) = %t: %t", input, got, want)
|
||||
{
|
||||
t.Run(tc.file, func(t *testing.T) {
|
||||
got := hasFilename(tc.file, tc.expectedFile)
|
||||
if got != tc.want {
|
||||
t.Errorf("hasFilename(%q, %q) = %t: %t", tc.file, tc.expectedFile, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
got := isReadme("")
|
||||
if got != false {
|
||||
t.Errorf("isReadme(%q) = %t: %t", "", got, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestContainsReadme(t *testing.T) {
|
||||
testZip := "testdata/module.zip"
|
||||
zipReader, err := zip.OpenReader(testZip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q) error: %v", testZip, err)
|
||||
}
|
||||
defer zipReader.Close()
|
||||
|
||||
if !containsReadme(zipReader) {
|
||||
t.Errorf("containsReadme(%q) = false, want true", testZip)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsReadmeEmptyZip(t *testing.T) {
|
||||
testZip := "testdata/empty.zip"
|
||||
zipReader, err := zip.OpenReader(testZip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q) error: %v", testZip, err)
|
||||
}
|
||||
defer zipReader.Close()
|
||||
|
||||
if containsReadme(zipReader) {
|
||||
t.Errorf("containsReadme(%q) = true, want false", testZip)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadZip(t *testing.T) {
|
||||
testZip := "testdata/module.zip"
|
||||
zipReader, err := zip.OpenReader(testZip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q) error: %v", testZip, err)
|
||||
}
|
||||
defer zipReader.Close()
|
||||
|
||||
got, err := readReadme(zipReader)
|
||||
if err != nil {
|
||||
t.Errorf("readReadme(%q) error: %v", testZip, err)
|
||||
}
|
||||
|
||||
testReadmeFilename := "testdata/my/module/README.md"
|
||||
want, err := ioutil.ReadFile(testReadmeFilename)
|
||||
if err != nil {
|
||||
t.Errorf("readReadme(%q) error: %v", testReadmeFilename, err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(want, got) {
|
||||
t.Errorf("readReadme(%q) = %q, want %q", testZip, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadZipEmptyZip(t *testing.T) {
|
||||
testZip := "testdata/empty.zip"
|
||||
zipReader, err := zip.OpenReader(testZip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q) error: %v", testZip, err)
|
||||
}
|
||||
defer zipReader.Close()
|
||||
|
||||
_, err = readReadme(zipReader)
|
||||
if err != errReadmeNotFound {
|
||||
t.Errorf("readReadme(%q) error: %v, want %v", testZip, err, errReadmeNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeriesNameForModule(t *testing.T) {
|
||||
|
@ -171,61 +219,169 @@ func TestSeriesNameForModule(t *testing.T) {
|
|||
"my/module/v23456": "my/module",
|
||||
"v2/": "v2",
|
||||
} {
|
||||
got, err := seriesNameForModule(input)
|
||||
if err != nil {
|
||||
t.Errorf("seriesNameForModule(%q): %v", input, err)
|
||||
}
|
||||
if got != want {
|
||||
t.Errorf("seriesNameForModule(%q) = %q, want %q", input, got, want)
|
||||
}
|
||||
t.Run(input, func(t *testing.T) {
|
||||
got, err := seriesNameForModule(input)
|
||||
if err != nil {
|
||||
t.Errorf("seriesNameForModule(%q): %v", input, err)
|
||||
}
|
||||
if got != want {
|
||||
t.Errorf("seriesNameForModule(%q) = %q, want %q", input, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
want := errors.New("module name cannot be empty")
|
||||
if _, got := seriesNameForModule(""); got.Error() != want.Error() {
|
||||
t.Errorf("seriesNameForModule(%q) returned error: %v; want %v", "", got, want)
|
||||
wantErr := "module name cannot be empty"
|
||||
if _, err := seriesNameForModule(""); err == nil || err.Error() != wantErr {
|
||||
t.Errorf("seriesNameForModule(%q) returned error: %v; want %v", "", err, wantErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsFile(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
zip string
|
||||
File string
|
||||
Want bool
|
||||
}{
|
||||
{
|
||||
zip: "module.zip",
|
||||
File: "README",
|
||||
Want: true,
|
||||
},
|
||||
{
|
||||
zip: "module.zip",
|
||||
File: "LICENSE",
|
||||
Want: false,
|
||||
},
|
||||
{
|
||||
zip: "empty.zip",
|
||||
File: "README",
|
||||
Want: false,
|
||||
},
|
||||
{
|
||||
zip: "empty.zip",
|
||||
File: "LICENSE",
|
||||
Want: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.zip, func(t *testing.T) {
|
||||
name := filepath.Join("testdata", tc.zip)
|
||||
rc, err := zip.OpenReader(name)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q): %v", name, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
z := &rc.Reader
|
||||
|
||||
if got := containsFile(z, tc.File); got != tc.Want {
|
||||
t.Errorf("containsFile(%q, %q) = %t, want %t", name, tc.File, got, tc.Want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractFile(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
zip string
|
||||
file string
|
||||
err error
|
||||
}{
|
||||
{
|
||||
zip: "testdata/module.zip",
|
||||
file: "my/module@v1.0.0/README.md",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
zip: "testdata/empty.zip",
|
||||
file: "empty/nonexistent/README.md",
|
||||
err: errors.New(`zip does not contain "README.md"`),
|
||||
},
|
||||
} {
|
||||
t.Run(tc.zip, func(t *testing.T) {
|
||||
rc, err := zip.OpenReader(tc.zip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q): %v", tc.zip, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
z := &rc.Reader
|
||||
|
||||
got, err := extractFile(z, filepath.Base(tc.file))
|
||||
if err != nil {
|
||||
if tc.err == nil || tc.err.Error() != err.Error() {
|
||||
t.Errorf("extractFile(%q, %q): \n %v, want \n %v",
|
||||
tc.zip, filepath.Base(tc.file), err, tc.err)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
f := filepath.Join("testdata", tc.file)
|
||||
want, err := ioutil.ReadFile(f)
|
||||
if err != nil {
|
||||
t.Fatalf("ioutfil.ReadFile(%q) error: %v", f, err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(want, got) {
|
||||
t.Errorf("extractFile(%q, %q) = %q, want %q", tc.zip, tc.file, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractPackagesFromZip(t *testing.T) {
|
||||
testZip := "testdata/module.zip"
|
||||
zipReader, err := zip.OpenReader(testZip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q): %v", testZip, err)
|
||||
}
|
||||
for _, tc := range []struct {
|
||||
zip string
|
||||
name string
|
||||
version string
|
||||
packages map[string]*internal.Package
|
||||
err error
|
||||
}{
|
||||
{
|
||||
zip: "testdata/module.zip",
|
||||
name: "my/module",
|
||||
version: "v1.0.0",
|
||||
packages: map[string]*internal.Package{
|
||||
"foo": &internal.Package{
|
||||
Name: "foo",
|
||||
Path: "my/module/foo",
|
||||
},
|
||||
"bar": &internal.Package{
|
||||
Name: "bar",
|
||||
Path: "my/module/bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
zip: "testdata/empty.zip",
|
||||
name: "empty/module",
|
||||
version: "v1.0.0",
|
||||
packages: map[string]*internal.Package{},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
rc, err := zip.OpenReader(tc.zip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q): %v", tc.zip, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
z := &rc.Reader
|
||||
|
||||
name := "my/module"
|
||||
packages, err := extractPackagesFromZip(name, zipReader)
|
||||
if err != nil {
|
||||
t.Fatalf("zipToPackages(%q, %q): %v", name, testZip, err)
|
||||
}
|
||||
packages, err := extractPackagesFromZip(tc.name, tc.version, z)
|
||||
if err != nil && len(tc.packages) != 0 {
|
||||
t.Fatalf("zipToPackages(%q, %q): %v", tc.name, tc.zip, err)
|
||||
}
|
||||
|
||||
expectedNamesToPath := map[string]string{
|
||||
"foo": "my/module/foo",
|
||||
"bar": "my/module/bar",
|
||||
}
|
||||
for _, p := range packages {
|
||||
expectedPath, ok := expectedNamesToPath[p.Name]
|
||||
if !ok {
|
||||
t.Errorf("zipToPackages(%q, %q) returned unexpected package: %q", name, testZip, p.Name)
|
||||
}
|
||||
if expectedPath != p.Path {
|
||||
t.Errorf("zipToPackages(%q, %q) returned unexpected path for package %q: %q, want %q", name, testZip, p.Name, p.Path, expectedPath)
|
||||
}
|
||||
for _, got := range packages {
|
||||
want, ok := tc.packages[got.Name]
|
||||
if !ok {
|
||||
t.Errorf("zipToPackages(%q, %q) returned unexpected package: %q", tc.name, tc.zip, got.Name)
|
||||
}
|
||||
if want.Path != got.Path {
|
||||
t.Errorf("zipToPackages(%q, %q) returned unexpected path for package %q: %q, want %q",
|
||||
tc.name, tc.zip, got.Name, got.Path, want.Path)
|
||||
}
|
||||
|
||||
delete(expectedNamesToPath, p.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractPackagesFromZipEmptyZip(t *testing.T) {
|
||||
testZip := "testdata/empty.zip"
|
||||
zipReader, err := zip.OpenReader(testZip)
|
||||
if err != nil {
|
||||
t.Fatalf("zip.OpenReader(%q): %v", testZip, err)
|
||||
}
|
||||
|
||||
name := "empty/module"
|
||||
_, err = extractPackagesFromZip(name, zipReader)
|
||||
if !strings.HasSuffix(err.Error(), "returned 0 packages") {
|
||||
t.Fatalf("zipToPackages(%q, %q): %v", name, testZip, err)
|
||||
delete(tc.packages, got.Name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -5,44 +5,13 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"golang.org/x/discovery/internal"
|
||||
)
|
||||
|
||||
var (
|
||||
user = getEnv("GO_DISCOVERY_DATABASE_TEST_USER", "postgres")
|
||||
password = getEnv("GO_DISCOVERY_DATABASE_TEST_PASSWORD", "")
|
||||
host = getEnv("GO_DISCOVERY_DATABASE_TEST_HOST", "localhost")
|
||||
testdbname = getEnv("GO_DISCOVERY_DATABASE_TEST_NAME", "discovery-database-test")
|
||||
testdb = fmt.Sprintf("user=%s host=%s dbname=%s sslmode=disable", user, host, testdbname)
|
||||
)
|
||||
|
||||
func getEnv(key, fallback string) string {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func setupCleanDB(t *testing.T) (func(t *testing.T), *DB) {
|
||||
t.Helper()
|
||||
db, err := Open(testdb)
|
||||
if err != nil {
|
||||
t.Fatalf("Open(%q), error: %v", testdb, err)
|
||||
}
|
||||
cleanup := func(t *testing.T) {
|
||||
db.Exec(`TRUNCATE version_logs;`) // truncates version_logs
|
||||
db.Exec(`TRUNCATE versions CASCADE;`) // truncates versions and any tables that use versions as a foreign key.
|
||||
}
|
||||
return cleanup, db
|
||||
}
|
||||
|
||||
func TestPostgres_ReadAndWriteVersion(t *testing.T) {
|
||||
var series = &internal.Series{
|
||||
Name: "myseries",
|
||||
|
@ -103,7 +72,7 @@ func TestPostgres_ReadAndWriteVersion(t *testing.T) {
|
|||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
teardownTestCase, db := setupCleanDB(t)
|
||||
teardownTestCase, db := SetupCleanDB(t)
|
||||
defer teardownTestCase(t)
|
||||
|
||||
if err := db.InsertVersion(tc.versionData); tc.wantWriteErr != (err != nil) {
|
||||
|
@ -134,7 +103,7 @@ func TestPostgres_ReadAndWriteVersion(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPostgress_InsertVersionLogs(t *testing.T) {
|
||||
teardownTestCase, db := setupCleanDB(t)
|
||||
teardownTestCase, db := SetupCleanDB(t)
|
||||
defer teardownTestCase(t)
|
||||
|
||||
now := time.Now().UTC()
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// 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 postgres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var (
|
||||
user = getEnv("GO_DISCOVERY_DATABASE_TEST_USER", "postgres")
|
||||
password = getEnv("GO_DISCOVERY_DATABASE_TEST_PASSWORD", "")
|
||||
host = getEnv("GO_DISCOVERY_DATABASE_TEST_HOST", "localhost")
|
||||
testdbname = getEnv("GO_DISCOVERY_DATABASE_TEST_NAME", "discovery-database-test")
|
||||
testdb = fmt.Sprintf("user=%s host=%s dbname=%s sslmode=disable", user, host, testdbname)
|
||||
)
|
||||
|
||||
func getEnv(key, fallback string) string {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// SetupCleanDB is used to test functions that execute Postgres queries. It
|
||||
// should only ever be used for testing. It makes a connection to a test
|
||||
// Postgres database and truncates all the tables in the database after the
|
||||
// test is complete.
|
||||
func SetupCleanDB(t *testing.T) (func(t *testing.T), *DB) {
|
||||
t.Helper()
|
||||
db, err := Open(testdb)
|
||||
if err != nil {
|
||||
t.Fatalf("Open(%q), error: %v", testdb, err)
|
||||
}
|
||||
cleanup := func(t *testing.T) {
|
||||
// truncates series and any tables that uses it as a foreign key.
|
||||
// This includes: modules, versions, documents, packages, and dependencies.
|
||||
db.Exec(`TRUNCATE series CASCADE;`)
|
||||
db.Exec(`TRUNCATE version_logs;`) // truncates version_logs
|
||||
}
|
||||
return cleanup, db
|
||||
}
|
|
@ -17,7 +17,6 @@ import (
|
|||
|
||||
// A Client is used by the fetch service to communicate with a module
|
||||
// proxy. It handles all methods defined by go help goproxy.
|
||||
// TODO(julieqiu): Implement GetList, GetMod, and GetZip.
|
||||
type Client struct {
|
||||
url string // URL of the module proxy web server
|
||||
}
|
||||
|
@ -54,6 +53,11 @@ func (c *Client) GetInfo(name, version string) (*VersionInfo, error) {
|
|||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
if r.StatusCode < 200 || r.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("http.Get(%q) returned response: %d (%q)",
|
||||
c.infoURL(name, version), r.StatusCode, r.Status)
|
||||
}
|
||||
|
||||
var v VersionInfo
|
||||
if err = json.NewDecoder(r.Body).Decode(&v); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -6,30 +6,10 @@ package proxy
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
proxy *httptest.Server
|
||||
client *Client
|
||||
}
|
||||
|
||||
func setupTestCase(t *testing.T) (func(t *testing.T), *testCase) {
|
||||
proxy := httptest.NewServer(http.FileServer(http.Dir("testdata/modproxy/proxy")))
|
||||
tc := testCase{
|
||||
proxy: proxy,
|
||||
client: New(proxy.URL),
|
||||
}
|
||||
|
||||
fn := func(t *testing.T) {
|
||||
proxy.Close()
|
||||
}
|
||||
return fn, &tc
|
||||
}
|
||||
|
||||
func TestCleanURL(t *testing.T) {
|
||||
for raw, expected := range map[string]string{
|
||||
"http://localhost:7000/index": "http://localhost:7000/index",
|
||||
|
@ -43,12 +23,12 @@ func TestCleanURL(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetInfo(t *testing.T) {
|
||||
teardownTestCase, testCase := setupTestCase(t)
|
||||
teardownTestCase, client := SetupTestProxyClient(t)
|
||||
defer teardownTestCase(t)
|
||||
|
||||
name := "my/module"
|
||||
version := "v1.0.0"
|
||||
info, err := testCase.client.GetInfo(name, version)
|
||||
info, err := client.GetInfo(name, version)
|
||||
if err != nil {
|
||||
t.Errorf("GetInfo(%q, %q) error: %v", name, version, err)
|
||||
}
|
||||
|
@ -64,24 +44,24 @@ func TestGetInfo(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetInfoVersionDoesNotExist(t *testing.T) {
|
||||
teardownTestCase, testCase := setupTestCase(t)
|
||||
teardownTestCase, client := SetupTestProxyClient(t)
|
||||
defer teardownTestCase(t)
|
||||
|
||||
name := "my/module"
|
||||
version := "v3.0.0"
|
||||
info, _ := testCase.client.GetInfo(name, version)
|
||||
info, _ := client.GetInfo(name, version)
|
||||
if info != nil {
|
||||
t.Errorf("GetInfo(%q, %q) = %v, want %v", name, version, info, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetZip(t *testing.T) {
|
||||
teardownTestCase, testCase := setupTestCase(t)
|
||||
teardownTestCase, client := SetupTestProxyClient(t)
|
||||
defer teardownTestCase(t)
|
||||
|
||||
name := "my/module"
|
||||
version := "v1.0.0"
|
||||
zipReader, err := testCase.client.GetZip(name, version)
|
||||
zipReader, err := client.GetZip(name, version)
|
||||
if err != nil {
|
||||
t.Errorf("GetZip(%q, %q) error: %v", name, version, err)
|
||||
}
|
||||
|
@ -108,15 +88,15 @@ func TestGetZip(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetZipNonExist(t *testing.T) {
|
||||
teardownTestCase, testCase := setupTestCase(t)
|
||||
teardownTestCase, client := SetupTestProxyClient(t)
|
||||
defer teardownTestCase(t)
|
||||
|
||||
name := "my/nonexistmodule"
|
||||
version := "v1.0.0"
|
||||
expectedErr := fmt.Sprintf("http.Get(%q) returned response: %d (%q)",
|
||||
testCase.client.zipURL(name, version), 404, "404 Not Found")
|
||||
client.zipURL(name, version), 404, "404 Not Found")
|
||||
|
||||
if _, err := testCase.client.GetZip(name, version); err.Error() != expectedErr {
|
||||
if _, err := client.GetZip(name, version); err.Error() != expectedErr {
|
||||
t.Errorf("GetZip(%q, %q) returned error %v, want %v", name, version, err, expectedErr)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// 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 proxy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// SetupTestProxyClient creates a module proxy for testing using static files
|
||||
// stored in internal/proxy/testdata/modproxy/proxy. It returns a function
|
||||
// for tearing down the proxy after the test is completed and a Client for
|
||||
// interacting with the test proxy. The following module versions are supported
|
||||
// by the proxy: (1) my/module v1.0.0 (2) my/module v1.1.0 (3) my/module v1.1.1
|
||||
// (4) my/module/v2 v2.0.0.
|
||||
func SetupTestProxyClient(t *testing.T) (func(t *testing.T), *Client) {
|
||||
t.Helper()
|
||||
proxyDataDir := "../proxy/testdata/modproxy/proxy"
|
||||
absPath, err := filepath.Abs(proxyDataDir)
|
||||
if err != nil {
|
||||
t.Fatalf("filepath.Abs(%q): %v", proxyDataDir, err)
|
||||
}
|
||||
|
||||
p := httptest.NewServer(http.FileServer(http.Dir(absPath)))
|
||||
client := New(p.URL)
|
||||
|
||||
expectedVersions := [][]string{
|
||||
[]string{"my/module", "v1.0.0"},
|
||||
[]string{"my/module", "v1.1.0"},
|
||||
[]string{"my/module", "v1.1.1"},
|
||||
[]string{"my/module/v2", "v2.0.0"},
|
||||
}
|
||||
|
||||
for _, v := range expectedVersions {
|
||||
if _, err := client.GetInfo(v[0], v[1]); err != nil {
|
||||
t.Fatalf("client.GetInfo(%q, %q): %v", v[0], v[1], err)
|
||||
}
|
||||
}
|
||||
|
||||
fn := func(t *testing.T) {
|
||||
p.Close()
|
||||
}
|
||||
return fn, client
|
||||
}
|
1
internal/proxy/testdata/modproxy/proxy/my/module/@v/my/module@v1.0.0/LICENSE
поставляемый
Normal file
1
internal/proxy/testdata/modproxy/proxy/my/module/@v/my/module@v1.0.0/LICENSE
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
LICENSE FILE FOR TESTING.
|
1
internal/proxy/testdata/modproxy/proxy/my/module/@v/my/module@v1.0.0/README.md
поставляемый
Normal file
1
internal/proxy/testdata/modproxy/proxy/my/module/@v/my/module@v1.0.0/README.md
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
README FILE FOR TESTING.
|
1
internal/proxy/testdata/modproxy/proxy/my/module/@v/my/module@v1.0.0/go.mod
поставляемый
Normal file
1
internal/proxy/testdata/modproxy/proxy/my/module/@v/my/module@v1.0.0/go.mod
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
module my/module
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче