From 97f80cd5504df5e234a0ce7ba9a0f412468307fb Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Wed, 13 Feb 2019 14:14:21 -0500 Subject: [PATCH] godoc/dl, godoc/proxy, godoc/short, internal/memcache: delete These packages existed only to power cmd/godoc for the purpose of serving the golang.org website. That functionality has moved into x/website as part of golang/go#29206. x/website has become the canonical source of golang.org in CL 162157, the golang.org-serving code was removed from cmd/godoc in CL 162400, and these packages can be deleted too now. This removes the last dependency on the cloud.google.com/go module, which results in a significant reduction of the number of indirect dependencies in x/tools (this is due to issue golang/go#29935, which affects the current version of the cloud.google.com/go module). Run go mod tidy (using Go 1.12 RC 1). Updates golang/go#29206 Updates golang/go#29981 Change-Id: If07e3ccae8538b3ebd51af64b6af5be5463f4906 Reviewed-on: https://go-review.googlesource.com/c/162401 Reviewed-by: Bryan C. Mills Reviewed-by: Channing Kimble-Brown Reviewed-by: Michael Matloob --- go.mod | 3 +- go.sum | 140 ------------ godoc/dl/dl.go | 353 ----------------------------- godoc/dl/dl_test.go | 159 ------------- godoc/dl/server.go | 266 ---------------------- godoc/dl/tmpl.go | 277 ---------------------- godoc/proxy/proxy.go | 170 -------------- godoc/short/short.go | 186 --------------- godoc/short/tmpl.go | 119 ---------- internal/memcache/memcache.go | 159 ------------- internal/memcache/memcache_test.go | 85 ------- 11 files changed, 1 insertion(+), 1916 deletions(-) delete mode 100644 godoc/dl/dl.go delete mode 100644 godoc/dl/dl_test.go delete mode 100644 godoc/dl/server.go delete mode 100644 godoc/dl/tmpl.go delete mode 100644 godoc/proxy/proxy.go delete mode 100644 godoc/short/short.go delete mode 100644 godoc/short/tmpl.go delete mode 100644 internal/memcache/memcache.go delete mode 100644 internal/memcache/memcache_test.go diff --git a/go.mod b/go.mod index b8b0580f..2d6246ed 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,7 @@ module golang.org/x/tools require ( - cloud.google.com/go v0.36.0 - github.com/gomodule/redigo v2.0.0+incompatible golang.org/x/net v0.0.0-20190213061140-3a22650c66bd + golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect google.golang.org/appengine v1.4.0 ) diff --git a/go.sum b/go.sum index 91a0f442..24edbf49 100644 --- a/go.sum +++ b/go.sum @@ -1,150 +1,10 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8= -cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 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/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -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/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3 h1:siORttZ36U2R/WjiJuDz8znElWBiAlO9rVt+mqJt0Cc= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -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.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -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= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497 h1:GXMDsk4xWZCVzkAWCabrabzCCVmfiYSw72f1K/S9QIY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.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 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922 h1:mBVYJnbrXLA/ZCBTCe7PtEgAUP+1bg92qTaFoPHdz+8= -google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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= diff --git a/godoc/dl/dl.go b/godoc/dl/dl.go deleted file mode 100644 index aaa7af41..00000000 --- a/godoc/dl/dl.go +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// Package dl implements a simple downloads frontend server. -// -// It accepts HTTP POST requests to create a new download metadata entity, and -// lists entities with sorting and filtering. -// It is designed to run only on the instance of godoc that serves golang.org. -package dl - -import ( - "fmt" - "html/template" - "regexp" - "sort" - "strconv" - "strings" - "time" -) - -const ( - downloadBaseURL = "https://dl.google.com/go/" - cacheKey = "download_list_3" // increment if listTemplateData changes - cacheDuration = time.Hour -) - -// File represents a file on the golang.org downloads page. -// It should be kept in sync with the upload code in x/build/cmd/release. -type File struct { - Filename string `json:"filename"` - OS string `json:"os"` - Arch string `json:"arch"` - Version string `json:"version"` - Checksum string `json:"-" datastore:",noindex"` // SHA1; deprecated - ChecksumSHA256 string `json:"sha256" datastore:",noindex"` - Size int64 `json:"size" datastore:",noindex"` - Kind string `json:"kind"` // "archive", "installer", "source" - Uploaded time.Time `json:"-"` -} - -func (f File) ChecksumType() string { - if f.ChecksumSHA256 != "" { - return "SHA256" - } - return "SHA1" -} - -func (f File) PrettyChecksum() string { - if f.ChecksumSHA256 != "" { - return f.ChecksumSHA256 - } - return f.Checksum -} - -func (f File) PrettyOS() string { - if f.OS == "darwin" { - switch { - case strings.Contains(f.Filename, "osx10.8"): - return "OS X 10.8+" - case strings.Contains(f.Filename, "osx10.6"): - return "OS X 10.6+" - } - } - return pretty(f.OS) -} - -func (f File) PrettySize() string { - const mb = 1 << 20 - if f.Size == 0 { - return "" - } - if f.Size < mb { - // All Go releases are >1mb, but handle this case anyway. - return fmt.Sprintf("%v bytes", f.Size) - } - return fmt.Sprintf("%.0fMB", float64(f.Size)/mb) -} - -var primaryPorts = map[string]bool{ - "darwin/amd64": true, - "linux/386": true, - "linux/amd64": true, - "linux/armv6l": true, - "windows/386": true, - "windows/amd64": true, -} - -func (f File) PrimaryPort() bool { - if f.Kind == "source" { - return true - } - return primaryPorts[f.OS+"/"+f.Arch] -} - -func (f File) Highlight() bool { - switch { - case f.Kind == "source": - return true - case f.Arch == "amd64" && f.OS == "linux": - return true - case f.Arch == "amd64" && f.Kind == "installer": - switch f.OS { - case "windows": - return true - case "darwin": - if !strings.Contains(f.Filename, "osx10.6") { - return true - } - } - } - return false -} - -func (f File) URL() string { - return downloadBaseURL + f.Filename -} - -type Release struct { - Version string `json:"version"` - Stable bool `json:"stable"` - Files []File `json:"files"` - Visible bool `json:"-"` // show files on page load - SplitPortTable bool `json:"-"` // whether files should be split by primary/other ports. -} - -type Feature struct { - // The File field will be filled in by the first stable File - // whose name matches the given fileRE. - File - fileRE *regexp.Regexp - - Platform string // "Microsoft Windows", "Apple macOS", "Linux" - Requirements string // "Windows XP and above, 64-bit Intel Processor" -} - -// featuredFiles lists the platforms and files to be featured -// at the top of the downloads page. -var featuredFiles = []Feature{ - { - Platform: "Microsoft Windows", - Requirements: "Windows 7 or later, Intel 64-bit processor", - fileRE: regexp.MustCompile(`\.windows-amd64\.msi$`), - }, - { - Platform: "Apple macOS", - Requirements: "macOS 10.10 or later, Intel 64-bit processor", - fileRE: regexp.MustCompile(`\.darwin-amd64(-osx10\.8)?\.pkg$`), - }, - { - Platform: "Linux", - Requirements: "Linux 2.6.23 or later, Intel 64-bit processor", - fileRE: regexp.MustCompile(`\.linux-amd64\.tar\.gz$`), - }, - { - Platform: "Source", - fileRE: regexp.MustCompile(`\.src\.tar\.gz$`), - }, -} - -// data to send to the template; increment cacheKey if you change this. -type listTemplateData struct { - Featured []Feature - Stable, Unstable, Archive []Release -} - -var ( - listTemplate = template.Must(template.New("").Funcs(templateFuncs).Parse(templateHTML)) - templateFuncs = template.FuncMap{"pretty": pretty} -) - -func filesToFeatured(fs []File) (featured []Feature) { - for _, feature := range featuredFiles { - for _, file := range fs { - if feature.fileRE.MatchString(file.Filename) { - feature.File = file - featured = append(featured, feature) - break - } - } - } - return -} - -func filesToReleases(fs []File) (stable, unstable, archive []Release) { - sort.Sort(fileOrder(fs)) - - var r *Release - var stableMaj, stableMin int - add := func() { - if r == nil { - return - } - if !r.Stable { - if len(unstable) != 0 { - // Only show one (latest) unstable version. - return - } - maj, min, _ := parseVersion(r.Version) - if maj < stableMaj || maj == stableMaj && min <= stableMin { - // Display unstable version only if newer than the - // latest stable release. - return - } - unstable = append(unstable, *r) - return - } - - // Reports whether the release is the most recent minor version of the - // two most recent major versions. - shouldAddStable := func() bool { - if len(stable) >= 2 { - // Show up to two stable versions. - return false - } - if len(stable) == 0 { - // Most recent stable version. - stableMaj, stableMin, _ = parseVersion(r.Version) - return true - } - if maj, _, _ := parseVersion(r.Version); maj == stableMaj { - // Older minor version of most recent major version. - return false - } - // Second most recent stable version. - return true - } - if !shouldAddStable() { - archive = append(archive, *r) - return - } - - // Split the file list into primary/other ports for the stable releases. - // NOTE(cbro): This is only done for stable releases because maintaining the historical - // nature of primary/other ports for older versions is infeasible. - // If freebsd is considered primary some time in the future, we'd not want to - // mark all of the older freebsd binaries as "primary". - // It might be better if we set that as a flag when uploading. - r.SplitPortTable = true - r.Visible = true // Toggle open all stable releases. - stable = append(stable, *r) - } - for _, f := range fs { - if r == nil || f.Version != r.Version { - add() - r = &Release{ - Version: f.Version, - Stable: isStable(f.Version), - } - } - r.Files = append(r.Files, f) - } - add() - return -} - -// isStable reports whether the version string v is a stable version. -func isStable(v string) bool { - return !strings.Contains(v, "beta") && !strings.Contains(v, "rc") -} - -type fileOrder []File - -func (s fileOrder) Len() int { return len(s) } -func (s fileOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s fileOrder) Less(i, j int) bool { - a, b := s[i], s[j] - if av, bv := a.Version, b.Version; av != bv { - return versionLess(av, bv) - } - if a.OS != b.OS { - return a.OS < b.OS - } - if a.Arch != b.Arch { - return a.Arch < b.Arch - } - if a.Kind != b.Kind { - return a.Kind < b.Kind - } - return a.Filename < b.Filename -} - -func versionLess(a, b string) bool { - // Put stable releases first. - if isStable(a) != isStable(b) { - return isStable(a) - } - maja, mina, ta := parseVersion(a) - majb, minb, tb := parseVersion(b) - if maja == majb { - if mina == minb { - return ta >= tb - } - return mina >= minb - } - return maja >= majb -} - -func parseVersion(v string) (maj, min int, tail string) { - if i := strings.Index(v, "beta"); i > 0 { - tail = v[i:] - v = v[:i] - } - if i := strings.Index(v, "rc"); i > 0 { - tail = v[i:] - v = v[:i] - } - p := strings.Split(strings.TrimPrefix(v, "go1."), ".") - maj, _ = strconv.Atoi(p[0]) - if len(p) < 2 { - return - } - min, _ = strconv.Atoi(p[1]) - return -} - -func validUser(user string) bool { - switch user { - case "adg", "bradfitz", "cbro", "andybons", "valsorda", "dmitshur", "katiehockman", "julieqiu": - return true - } - return false -} - -var ( - fileRe = regexp.MustCompile(`^go[0-9a-z.]+\.[0-9a-z.-]+\.(tar\.gz|pkg|msi|zip)$`) - goGetRe = regexp.MustCompile(`^go[0-9a-z.]+\.[0-9a-z.-]+$`) -) - -// pretty returns a human-readable version of the given OS, Arch, or Kind. -func pretty(s string) string { - t, ok := prettyStrings[s] - if !ok { - return s - } - return t -} - -var prettyStrings = map[string]string{ - "darwin": "macOS", - "freebsd": "FreeBSD", - "linux": "Linux", - "windows": "Windows", - - "386": "x86", - "amd64": "x86-64", - "armv6l": "ARMv6", - "arm64": "ARMv8", - - "archive": "Archive", - "installer": "Installer", - "source": "Source", -} diff --git a/godoc/dl/dl_test.go b/godoc/dl/dl_test.go deleted file mode 100644 index 9ea5f620..00000000 --- a/godoc/dl/dl_test.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package dl - -import ( - "sort" - "strings" - "testing" -) - -func TestParseVersion(t *testing.T) { - for _, c := range []struct { - in string - maj, min int - tail string - }{ - {"go1.5", 5, 0, ""}, - {"go1.5beta1", 5, 0, "beta1"}, - {"go1.5.1", 5, 1, ""}, - {"go1.5.1rc1", 5, 1, "rc1"}, - } { - maj, min, tail := parseVersion(c.in) - if maj != c.maj || min != c.min || tail != c.tail { - t.Errorf("parseVersion(%q) = %v, %v, %q; want %v, %v, %q", - c.in, maj, min, tail, c.maj, c.min, c.tail) - } - } -} - -func TestFileOrder(t *testing.T) { - fs := []File{ - {Filename: "go1.3.src.tar.gz", Version: "go1.3", OS: "", Arch: "", Kind: "source"}, - {Filename: "go1.3.1.src.tar.gz", Version: "go1.3.1", OS: "", Arch: "", Kind: "source"}, - {Filename: "go1.3.linux-amd64.tar.gz", Version: "go1.3", OS: "linux", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.3.1.linux-amd64.tar.gz", Version: "go1.3.1", OS: "linux", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.3.darwin-amd64.tar.gz", Version: "go1.3", OS: "darwin", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.3.darwin-amd64.pkg", Version: "go1.3", OS: "darwin", Arch: "amd64", Kind: "installer"}, - {Filename: "go1.3.darwin-386.tar.gz", Version: "go1.3", OS: "darwin", Arch: "386", Kind: "archive"}, - {Filename: "go1.3beta1.linux-amd64.tar.gz", Version: "go1.3beta1", OS: "linux", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.3beta2.linux-amd64.tar.gz", Version: "go1.3beta2", OS: "linux", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.3rc1.linux-amd64.tar.gz", Version: "go1.3rc1", OS: "linux", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.2.linux-amd64.tar.gz", Version: "go1.2", OS: "linux", Arch: "amd64", Kind: "archive"}, - {Filename: "go1.2.2.linux-amd64.tar.gz", Version: "go1.2.2", OS: "linux", Arch: "amd64", Kind: "archive"}, - } - sort.Sort(fileOrder(fs)) - var s []string - for _, f := range fs { - s = append(s, f.Filename) - } - got := strings.Join(s, "\n") - want := strings.Join([]string{ - "go1.3.1.src.tar.gz", - "go1.3.1.linux-amd64.tar.gz", - "go1.3.src.tar.gz", - "go1.3.darwin-386.tar.gz", - "go1.3.darwin-amd64.tar.gz", - "go1.3.darwin-amd64.pkg", - "go1.3.linux-amd64.tar.gz", - "go1.2.2.linux-amd64.tar.gz", - "go1.2.linux-amd64.tar.gz", - "go1.3rc1.linux-amd64.tar.gz", - "go1.3beta2.linux-amd64.tar.gz", - "go1.3beta1.linux-amd64.tar.gz", - }, "\n") - if got != want { - t.Errorf("sort order is\n%s\nwant:\n%s", got, want) - } -} - -func TestFilesToReleases(t *testing.T) { - fs := []File{ - {Version: "go1.7.4", OS: "darwin"}, - {Version: "go1.7.4", OS: "windows"}, - {Version: "go1.7", OS: "darwin"}, - {Version: "go1.7", OS: "windows"}, - {Version: "go1.6.2", OS: "darwin"}, - {Version: "go1.6.2", OS: "windows"}, - {Version: "go1.6", OS: "darwin"}, - {Version: "go1.6", OS: "windows"}, - {Version: "go1.5.2", OS: "darwin"}, - {Version: "go1.5.2", OS: "windows"}, - {Version: "go1.5", OS: "darwin"}, - {Version: "go1.5", OS: "windows"}, - {Version: "go1.5beta1", OS: "windows"}, - } - stable, unstable, archive := filesToReleases(fs) - if got, want := list(stable), "go1.7.4, go1.6.2"; got != want { - t.Errorf("stable = %q; want %q", got, want) - } - if got, want := list(unstable), ""; got != want { - t.Errorf("unstable = %q; want %q", got, want) - } - if got, want := list(archive), "go1.7, go1.6, go1.5.2, go1.5"; got != want { - t.Errorf("archive = %q; want %q", got, want) - } -} - -func TestOldUnstableNotShown(t *testing.T) { - fs := []File{ - {Version: "go1.7.4"}, - {Version: "go1.7"}, - {Version: "go1.7beta1"}, - } - _, unstable, _ := filesToReleases(fs) - if len(unstable) != 0 { - t.Errorf("got unstable, want none") - } -} - -// A new beta should show up under unstable, but not show up under archive. See golang.org/issue/29669. -func TestNewUnstableShownOnce(t *testing.T) { - fs := []File{ - {Version: "go1.12beta2"}, - {Version: "go1.11.4"}, - {Version: "go1.11"}, - {Version: "go1.10.7"}, - {Version: "go1.10"}, - {Version: "go1.9"}, - } - stable, unstable, archive := filesToReleases(fs) - if got, want := list(stable), "go1.11.4, go1.10.7"; got != want { - t.Errorf("stable = %q; want %q", got, want) - } - if got, want := list(unstable), "go1.12beta2"; got != want { - t.Errorf("unstable = %q; want %q", got, want) - } - if got, want := list(archive), "go1.11, go1.10, go1.9"; got != want { - t.Errorf("archive = %q; want %q", got, want) - } -} - -func TestUnstableShown(t *testing.T) { - fs := []File{ - {Version: "go1.8beta2"}, - {Version: "go1.8rc1"}, - {Version: "go1.7.4"}, - {Version: "go1.7"}, - {Version: "go1.7beta1"}, - } - _, unstable, _ := filesToReleases(fs) - // Show RCs ahead of betas. - if got, want := list(unstable), "go1.8rc1"; got != want { - t.Errorf("unstable = %q; want %q", got, want) - } -} - -// list returns a version list string for the given releases. -func list(rs []Release) string { - var s string - for i, r := range rs { - if i > 0 { - s += ", " - } - s += r.Version - } - return s -} diff --git a/godoc/dl/server.go b/godoc/dl/server.go deleted file mode 100644 index 43fa4533..00000000 --- a/godoc/dl/server.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// +build golangorg - -package dl - -import ( - "context" - "crypto/hmac" - "crypto/md5" - "encoding/json" - "fmt" - "html" - "io" - "log" - "net/http" - "strings" - "sync" - "time" - - "cloud.google.com/go/datastore" - "golang.org/x/tools/godoc/env" - "golang.org/x/tools/internal/memcache" -) - -type server struct { - datastore *datastore.Client - memcache *memcache.CodecClient -} - -func RegisterHandlers(mux *http.ServeMux, dc *datastore.Client, mc *memcache.Client) { - s := server{dc, mc.WithCodec(memcache.Gob)} - mux.HandleFunc("/dl", s.getHandler) - mux.HandleFunc("/dl/", s.getHandler) // also serves listHandler - mux.HandleFunc("/dl/upload", s.uploadHandler) - - // NOTE(cbro): this only needs to be run once per project, - // and should be behind an admin login. - // TODO(cbro): move into a locally-run program? or remove? - // mux.HandleFunc("/dl/init", initHandler) -} - -// rootKey is the ancestor of all File entities. -var rootKey = datastore.NameKey("FileRoot", "root", nil) - -func (h server) listHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - http.Error(w, "method not allowed", http.StatusMethodNotAllowed) - return - } - ctx := r.Context() - var d listTemplateData - - if err := h.memcache.Get(ctx, cacheKey, &d); err != nil { - if err != memcache.ErrCacheMiss { - log.Printf("ERROR cache get error: %v", err) - // NOTE(cbro): continue to hit datastore if the memcache is down. - } - - var fs []File - q := datastore.NewQuery("File").Ancestor(rootKey) - if _, err := h.datastore.GetAll(ctx, q, &fs); err != nil { - log.Printf("ERROR error listing: %v", err) - http.Error(w, "Could not get download page. Try again in a few minutes.", 500) - return - } - d.Stable, d.Unstable, d.Archive = filesToReleases(fs) - if len(d.Stable) > 0 { - d.Featured = filesToFeatured(d.Stable[0].Files) - } - - item := &memcache.Item{Key: cacheKey, Object: &d, Expiration: cacheDuration} - if err := h.memcache.Set(ctx, item); err != nil { - log.Printf("ERROR cache set error: %v", err) - } - } - - if r.URL.Query().Get("mode") == "json" { - w.Header().Set("Content-Type", "application/json") - enc := json.NewEncoder(w) - enc.SetIndent("", " ") - if err := enc.Encode(d.Stable); err != nil { - log.Printf("ERROR rendering JSON for releases: %v", err) - } - return - } - - if err := listTemplate.ExecuteTemplate(w, "root", d); err != nil { - log.Printf("ERROR executing template: %v", err) - } -} - -func (h server) uploadHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - http.Error(w, "method not allowed", http.StatusMethodNotAllowed) - return - } - ctx := r.Context() - - // Authenticate using a user token (same as gomote). - user := r.FormValue("user") - if !validUser(user) { - http.Error(w, "bad user", http.StatusForbidden) - return - } - if r.FormValue("key") != h.userKey(ctx, user) { - http.Error(w, "bad key", http.StatusForbidden) - return - } - - var f File - defer r.Body.Close() - if err := json.NewDecoder(r.Body).Decode(&f); err != nil { - log.Printf("ERROR decoding upload JSON: %v", err) - http.Error(w, "Something broke", http.StatusInternalServerError) - return - } - if f.Filename == "" { - http.Error(w, "Must provide Filename", http.StatusBadRequest) - return - } - if f.Uploaded.IsZero() { - f.Uploaded = time.Now() - } - k := datastore.NameKey("File", f.Filename, rootKey) - if _, err := h.datastore.Put(ctx, k, &f); err != nil { - log.Printf("ERROR File entity: %v", err) - http.Error(w, "could not put File entity", http.StatusInternalServerError) - return - } - if err := h.memcache.Delete(ctx, cacheKey); err != nil { - log.Printf("ERROR delete error: %v", err) - } - io.WriteString(w, "OK") -} - -func (h server) getHandler(w http.ResponseWriter, r *http.Request) { - isGoGet := (r.Method == "GET" || r.Method == "HEAD") && r.FormValue("go-get") == "1" - // For go get, we need to serve the same meta tags at /dl for cmd/go to - // validate against the import path. - if r.URL.Path == "/dl" && isGoGet { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - fmt.Fprintf(w, ` - -`) - return - } - if r.URL.Path == "/dl" { - http.Redirect(w, r, "/dl/", http.StatusFound) - return - } - - name := strings.TrimPrefix(r.URL.Path, "/dl/") - var redirectURL string - switch { - case name == "": - h.listHandler(w, r) - return - case fileRe.MatchString(name): - http.Redirect(w, r, downloadBaseURL+name, http.StatusFound) - return - case name == "gotip": - redirectURL = "https://godoc.org/golang.org/dl/gotip" - case goGetRe.MatchString(name): - redirectURL = "https://golang.org/dl/#" + name - default: - http.NotFound(w, r) - return - } - w.Header().Set("Content-Type", "text/html; charset=utf-8") - if !isGoGet { - w.Header().Set("Location", redirectURL) - } - fmt.Fprintf(w, ` - - - - - - -Nothing to see here; move along. - - -`, html.EscapeString(redirectURL), html.EscapeString(redirectURL)) -} - -func (h server) initHandler(w http.ResponseWriter, r *http.Request) { - var fileRoot struct { - Root string - } - ctx := r.Context() - k := rootKey - _, err := h.datastore.RunInTransaction(ctx, func(tx *datastore.Transaction) error { - err := tx.Get(k, &fileRoot) - if err != nil && err != datastore.ErrNoSuchEntity { - return err - } - _, err = tx.Put(k, &fileRoot) - return err - }, nil) - if err != nil { - http.Error(w, err.Error(), 500) - return - } - io.WriteString(w, "OK") -} - -func (h server) userKey(c context.Context, user string) string { - hash := hmac.New(md5.New, []byte(h.secret(c))) - hash.Write([]byte("user-" + user)) - return fmt.Sprintf("%x", hash.Sum(nil)) -} - -// Code below copied from x/build/app/key - -var theKey struct { - sync.RWMutex - builderKey -} - -type builderKey struct { - Secret string -} - -func (k *builderKey) Key() *datastore.Key { - return datastore.NameKey("BuilderKey", "root", nil) -} - -func (h server) secret(ctx context.Context) string { - // check with rlock - theKey.RLock() - k := theKey.Secret - theKey.RUnlock() - if k != "" { - return k - } - - // prepare to fill; check with lock and keep lock - theKey.Lock() - defer theKey.Unlock() - if theKey.Secret != "" { - return theKey.Secret - } - - // fill - if err := h.datastore.Get(ctx, theKey.Key(), &theKey.builderKey); err != nil { - if err == datastore.ErrNoSuchEntity { - // If the key is not stored in datastore, write it. - // This only happens at the beginning of a new deployment. - // The code is left here for SDK use and in case a fresh - // deployment is ever needed. "gophers rule" is not the - // real key. - if env.IsProd() { - panic("lost key from datastore") - } - theKey.Secret = "gophers rule" - h.datastore.Put(ctx, theKey.Key(), &theKey.builderKey) - return theKey.Secret - } - panic("cannot load builder key: " + err.Error()) - } - - return theKey.Secret -} diff --git a/godoc/dl/tmpl.go b/godoc/dl/tmpl.go deleted file mode 100644 index d086b696..00000000 --- a/godoc/dl/tmpl.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package dl - -// TODO(adg): refactor this to use the tools/godoc/static template. - -const templateHTML = ` -{{define "root"}} - - - - - Downloads - The Go Programming Language - - - - - - - - -
-
- -

Downloads

- -

-After downloading a binary release suitable for your system, -please follow the installation instructions. -

- -

-If you are building from source, -follow the source installation instructions. -

- -

-See the release history for more -information about Go releases. -

- -{{with .Featured}} - -{{range .}} -{{template "download" .}} -{{end}} -{{end}} - -
- -{{with .Stable}} -

Stable versions

-{{template "releases" .}} -{{end}} - -{{with .Unstable}} -

Unstable version

-{{template "releases" .}} -{{end}} - -{{with .Archive}} -
- -
-

Archived versions▾

- {{template "releases" .}} -
-
-{{end}} - - - -
-
- - - - - - -{{end}} - -{{define "releases"}} -{{range .}} -
- -
-

{{.Version}} ▾

- {{if .Stable}}{{else}} -

This is an unstable version of Go. Use with caution.

-

If you already have Go installed, you can install this version by running:

-
-go get golang.org/dl/{{.Version}}
-
-

Then, use the {{.Version}} command instead of the go command to use {{.Version}}.

- {{end}} - {{template "files" .}} -
-
-{{end}} -{{end}} - -{{define "files"}} - - - - - - - - - {{/* Use the checksum type of the first file for the column heading. */}} - - - -{{if .SplitPortTable}} - {{range .Files}}{{if .PrimaryPort}}{{template "file" .}}{{end}}{{end}} - - {{/* TODO(cbro): add a link to an explanatory doc page */}} - - {{range .Files}}{{if not .PrimaryPort}}{{template "file" .}}{{end}}{{end}} -{{else}} - {{range .Files}}{{template "file" .}}{{end}} -{{end}} -
File nameKindOSArchSize{{(index .Files 0).ChecksumType}} Checksum
Other Ports
-{{end}} - -{{define "file"}} - - {{.Filename}} - {{pretty .Kind}} - {{.PrettyOS}} - {{pretty .Arch}} - {{.PrettySize}} - {{.PrettyChecksum}} - -{{end}} - -{{define "download"}} - -
{{.Platform}}
-{{with .Requirements}}
{{.}}
{{end}} -
- {{.Filename}} - {{if .Size}}({{.PrettySize}}){{end}} -
-
-{{end}} -` diff --git a/godoc/proxy/proxy.go b/godoc/proxy/proxy.go deleted file mode 100644 index bb0e81c3..00000000 --- a/godoc/proxy/proxy.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2015 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 proxies requests to the playground's compile and share handlers. -// It is designed to run only on the instance of godoc that serves golang.org. -package proxy - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "strings" - "time" - - "golang.org/x/tools/godoc/env" -) - -const playgroundURL = "https://play.golang.org" - -type Request struct { - Body string -} - -type Response struct { - Errors string - Events []Event -} - -type Event struct { - Message string - Kind string // "stdout" or "stderr" - Delay time.Duration // time to wait before printing Message -} - -const expires = 7 * 24 * time.Hour // 1 week -var cacheControlHeader = fmt.Sprintf("public, max-age=%d", int(expires.Seconds())) - -func RegisterHandlers(mux *http.ServeMux) { - mux.HandleFunc("/compile", compile) - mux.HandleFunc("/share", share) -} - -func compile(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - http.Error(w, "I only answer to POST requests.", http.StatusMethodNotAllowed) - return - } - - ctx := r.Context() - - body := r.FormValue("body") - res := &Response{} - req := &Request{Body: body} - if err := makeCompileRequest(ctx, req, res); err != nil { - log.Printf("ERROR compile error: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - - var out interface{} - switch r.FormValue("version") { - case "2": - out = res - default: // "1" - out = struct { - CompileErrors string `json:"compile_errors"` - Output string `json:"output"` - }{res.Errors, flatten(res.Events)} - } - b, err := json.Marshal(out) - if err != nil { - log.Printf("ERROR encoding response: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - - expiresTime := time.Now().Add(expires).UTC() - w.Header().Set("Expires", expiresTime.Format(time.RFC1123)) - w.Header().Set("Cache-Control", cacheControlHeader) - w.Write(b) -} - -// makePlaygroundRequest sends the given Request to the playground compile -// endpoint and stores the response in the given Response. -func makeCompileRequest(ctx context.Context, req *Request, res *Response) error { - reqJ, err := json.Marshal(req) - if err != nil { - return fmt.Errorf("marshalling request: %v", err) - } - hReq, _ := http.NewRequest("POST", playgroundURL+"/compile", bytes.NewReader(reqJ)) - hReq.Header.Set("Content-Type", "application/json") - hReq = hReq.WithContext(ctx) - - r, err := http.DefaultClient.Do(hReq) - if err != nil { - return fmt.Errorf("making request: %v", err) - } - defer r.Body.Close() - - if r.StatusCode != http.StatusOK { - b, _ := ioutil.ReadAll(r.Body) - return fmt.Errorf("bad status: %v body:\n%s", r.Status, b) - } - - if err := json.NewDecoder(r.Body).Decode(res); err != nil { - return fmt.Errorf("unmarshalling response: %v", err) - } - return nil -} - -// flatten takes a sequence of Events and returns their contents, concatenated. -func flatten(seq []Event) string { - var buf bytes.Buffer - for _, e := range seq { - buf.WriteString(e.Message) - } - return buf.String() -} - -func share(w http.ResponseWriter, r *http.Request) { - if googleCN(r) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - - // HACK(cbro): use a simple proxy rather than httputil.ReverseProxy because of Issue #28168. - // TODO: investigate using ReverseProxy with a Director, unsetting whatever's necessary to make that work. - req, _ := http.NewRequest("POST", playgroundURL+"/share", r.Body) - req.Header.Set("Content-Type", r.Header.Get("Content-Type")) - req = req.WithContext(r.Context()) - resp, err := http.DefaultClient.Do(req) - if err != nil { - log.Printf("ERROR share error: %v", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - copyHeader := func(k string) { - if v := resp.Header.Get(k); v != "" { - w.Header().Set(k, v) - } - } - copyHeader("Content-Type") - copyHeader("Content-Length") - defer resp.Body.Close() - w.WriteHeader(resp.StatusCode) - io.Copy(w, resp.Body) -} - -func googleCN(r *http.Request) bool { - if r.FormValue("googlecn") != "" { - return true - } - if !env.IsProd() { - return false - } - if strings.HasSuffix(r.Host, ".cn") { - return true - } - switch r.Header.Get("X-AppEngine-Country") { - case "", "ZZ", "CN": - return true - } - return false -} diff --git a/godoc/short/short.go b/godoc/short/short.go deleted file mode 100644 index 7562ea69..00000000 --- a/godoc/short/short.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// +build golangorg - -// Package short implements a simple URL shortener, serving an administrative -// interface at /s and shortened urls from /s/key. -// It is designed to run only on the instance of godoc that serves golang.org. -package short - -// TODO(adg): collect statistics on URL visits - -import ( - "context" - "errors" - "fmt" - "html/template" - "io" - "log" - "net/http" - "net/url" - "regexp" - - "cloud.google.com/go/datastore" - "golang.org/x/tools/internal/memcache" - "google.golang.org/appengine/user" -) - -const ( - prefix = "/s" - kind = "Link" - baseURL = "https://golang.org" + prefix -) - -// Link represents a short link. -type Link struct { - Key, Target string -} - -var validKey = regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`) - -type server struct { - datastore *datastore.Client - memcache *memcache.CodecClient -} - -func RegisterHandlers(mux *http.ServeMux, dc *datastore.Client, mc *memcache.Client) { - s := server{dc, mc.WithCodec(memcache.JSON)} - mux.HandleFunc(prefix+"/", s.linkHandler) - - // TODO(cbro): move storage of the links to a text file in Gerrit. - // Disable the admin handler until that happens, since GAE Flex doesn't support - // the "google.golang.org/appengine/user" package. - // See golang.org/issue/29988 and golang.org/issue/27205#issuecomment-418673218. - // mux.HandleFunc(prefix, adminHandler) - mux.HandleFunc(prefix, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusForbidden) - io.WriteString(w, "Link creation temporarily unavailable. See golang.org/issue/29988.") - }) -} - -// linkHandler services requests to short URLs. -// http://golang.org/s/key -// It consults memcache and datastore for the Link for key. -// It then sends a redirects or an error message. -func (h server) linkHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - key := r.URL.Path[len(prefix)+1:] - if !validKey.MatchString(key) { - http.Error(w, "not found", http.StatusNotFound) - return - } - - var link Link - if err := h.memcache.Get(ctx, cacheKey(key), &link); err != nil { - k := datastore.NameKey(kind, key, nil) - err = h.datastore.Get(ctx, k, &link) - switch err { - case datastore.ErrNoSuchEntity: - http.Error(w, "not found", http.StatusNotFound) - return - default: // != nil - log.Printf("ERROR %q: %v", key, err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - case nil: - item := &memcache.Item{ - Key: cacheKey(key), - Object: &link, - } - if err := h.memcache.Set(ctx, item); err != nil { - log.Printf("WARNING %q: %v", key, err) - } - } - } - - http.Redirect(w, r, link.Target, http.StatusFound) -} - -var adminTemplate = template.Must(template.New("admin").Parse(templateHTML)) - -// adminHandler serves an administrative interface. -func (h server) adminHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - if !user.IsAdmin(ctx) { - http.Error(w, "forbidden", http.StatusForbidden) - return - } - - var newLink *Link - var doErr error - if r.Method == "POST" { - key := r.FormValue("key") - switch r.FormValue("do") { - case "Add": - newLink = &Link{key, r.FormValue("target")} - doErr = h.putLink(ctx, newLink) - case "Delete": - k := datastore.NameKey(kind, key, nil) - doErr = h.datastore.Delete(ctx, k) - default: - http.Error(w, "unknown action", http.StatusBadRequest) - } - err := h.memcache.Delete(ctx, cacheKey(key)) - if err != nil && err != memcache.ErrCacheMiss { - log.Printf("WARNING %q: %v", key, err) - } - } - - var links []*Link - q := datastore.NewQuery(kind).Order("Key") - if _, err := h.datastore.GetAll(ctx, q, &links); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - log.Printf("ERROR %v", err) - return - } - - // Put the new link in the list if it's not there already. - // (Eventual consistency means that it might not show up - // immediately, which might be confusing for the user.) - if newLink != nil && doErr == nil { - found := false - for i := range links { - if links[i].Key == newLink.Key { - found = true - break - } - } - if !found { - links = append([]*Link{newLink}, links...) - } - newLink = nil - } - - var data = struct { - BaseURL string - Prefix string - Links []*Link - New *Link - Error error - }{baseURL, prefix, links, newLink, doErr} - if err := adminTemplate.Execute(w, &data); err != nil { - log.Printf("ERROR adminTemplate: %v", err) - } -} - -// putLink validates the provided link and puts it into the datastore. -func (h server) putLink(ctx context.Context, link *Link) error { - if !validKey.MatchString(link.Key) { - return errors.New("invalid key; must match " + validKey.String()) - } - if _, err := url.Parse(link.Target); err != nil { - return fmt.Errorf("bad target: %v", err) - } - k := datastore.NameKey(kind, link.Key, nil) - _, err := h.datastore.Put(ctx, k, link) - return err -} - -// cacheKey returns a short URL key as a memcache key. -func cacheKey(key string) string { - return "link-" + key -} diff --git a/godoc/short/tmpl.go b/godoc/short/tmpl.go deleted file mode 100644 index 66f5401e..00000000 --- a/godoc/short/tmpl.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package short - -const templateHTML = ` - - - -golang.org URL shortener - - - - - - -{{with .Error}} - - - - - - -{{end}} - - - - - - - - - - - - - - -{{with .Links}} - - - - - -{{range .}} - - - - - -{{end}} -{{end}} - -
Error
{{.}}
KeyTarget
-
Short Link  
-
- - -
-
- - - - - - -` diff --git a/internal/memcache/memcache.go b/internal/memcache/memcache.go deleted file mode 100644 index be350f68..00000000 --- a/internal/memcache/memcache.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build golangorg - -// Package memcache provides a minimally compatible interface for -// google.golang.org/appengine/memcache -// and stores the data in Redis (e.g., via Cloud Memorystore). -package memcache - -import ( - "bytes" - "context" - "encoding/gob" - "encoding/json" - "errors" - "time" - - "github.com/gomodule/redigo/redis" -) - -var ErrCacheMiss = errors.New("memcache: cache miss") - -func New(addr string) *Client { - const maxConns = 20 - - pool := redis.NewPool(func() (redis.Conn, error) { - return redis.Dial("tcp", addr) - }, maxConns) - - return &Client{ - pool: pool, - } -} - -type Client struct { - pool *redis.Pool -} - -type CodecClient struct { - client *Client - codec Codec -} - -type Item struct { - Key string - Value []byte - Object interface{} // Used with Codec. - Expiration time.Duration // Read-only. -} - -func (c *Client) WithCodec(codec Codec) *CodecClient { - return &CodecClient{ - c, codec, - } -} - -func (c *Client) Delete(ctx context.Context, key string) error { - conn, err := c.pool.GetContext(ctx) - if err != nil { - return err - } - defer conn.Close() - - _, err = conn.Do("DEL", key) - return err -} - -func (c *CodecClient) Delete(ctx context.Context, key string) error { - return c.client.Delete(ctx, key) -} - -func (c *Client) Set(ctx context.Context, item *Item) error { - if item.Value == nil { - return errors.New("nil item value") - } - return c.set(ctx, item.Key, item.Value, item.Expiration) -} - -func (c *CodecClient) Set(ctx context.Context, item *Item) error { - if item.Object == nil { - return errors.New("nil object value") - } - b, err := c.codec.Marshal(item.Object) - if err != nil { - return err - } - return c.client.set(ctx, item.Key, b, item.Expiration) -} - -func (c *Client) set(ctx context.Context, key string, value []byte, expiration time.Duration) error { - conn, err := c.pool.GetContext(ctx) - if err != nil { - return err - } - defer conn.Close() - - if expiration == 0 { - _, err := conn.Do("SET", key, value) - return err - } - - // NOTE(cbro): redis does not support expiry in units more granular than a second. - exp := int64(expiration.Seconds()) - if exp == 0 { - // Redis doesn't allow a zero expiration, delete the key instead. - _, err := conn.Do("DEL", key) - return err - } - - _, err = conn.Do("SETEX", key, exp, value) - return err -} - -// Get gets the item. -func (c *Client) Get(ctx context.Context, key string) ([]byte, error) { - conn, err := c.pool.GetContext(ctx) - if err != nil { - return nil, err - } - defer conn.Close() - - b, err := redis.Bytes(conn.Do("GET", key)) - if err == redis.ErrNil { - err = ErrCacheMiss - } - return b, err -} - -func (c *CodecClient) Get(ctx context.Context, key string, v interface{}) error { - b, err := c.client.Get(ctx, key) - if err != nil { - return err - } - return c.codec.Unmarshal(b, v) -} - -var ( - Gob = Codec{gobMarshal, gobUnmarshal} - JSON = Codec{json.Marshal, json.Unmarshal} -) - -type Codec struct { - Marshal func(interface{}) ([]byte, error) - Unmarshal func([]byte, interface{}) error -} - -func gobMarshal(v interface{}) ([]byte, error) { - var buf bytes.Buffer - if err := gob.NewEncoder(&buf).Encode(v); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func gobUnmarshal(data []byte, v interface{}) error { - return gob.NewDecoder(bytes.NewBuffer(data)).Decode(v) -} diff --git a/internal/memcache/memcache_test.go b/internal/memcache/memcache_test.go deleted file mode 100644 index 49602f71..00000000 --- a/internal/memcache/memcache_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build golangorg - -package memcache - -import ( - "context" - "os" - "testing" - "time" -) - -func getClient(t *testing.T) *Client { - t.Helper() - - addr := os.Getenv("GOLANG_REDIS_ADDR") - if addr == "" { - t.Skip("skipping because GOLANG_REDIS_ADDR is unset") - } - - return New(addr) -} - -func TestCacheMiss(t *testing.T) { - c := getClient(t) - ctx := context.Background() - - if _, err := c.Get(ctx, "doesnotexist"); err != ErrCacheMiss { - t.Errorf("got %v; want ErrCacheMiss", err) - } -} - -func TestExpiry(t *testing.T) { - c := getClient(t).WithCodec(Gob) - ctx := context.Background() - - key := "testexpiry" - - firstTime := time.Now() - err := c.Set(ctx, &Item{ - Key: key, - Object: firstTime, - Expiration: 3500 * time.Millisecond, // NOTE: check that non-rounded expiries work. - }) - if err != nil { - t.Fatalf("Set: %v", err) - } - - var newTime time.Time - if err := c.Get(ctx, key, &newTime); err != nil { - t.Fatalf("Get: %v", err) - } - if !firstTime.Equal(newTime) { - t.Errorf("Get: got value %v, want %v", newTime, firstTime) - } - - time.Sleep(4 * time.Second) - - if err := c.Get(ctx, key, &newTime); err != ErrCacheMiss { - t.Errorf("Get: got %v, want ErrCacheMiss", err) - } -} - -func TestShortExpiry(t *testing.T) { - c := getClient(t).WithCodec(Gob) - ctx := context.Background() - - key := "testshortexpiry" - - err := c.Set(ctx, &Item{ - Key: key, - Value: []byte("ok"), - Expiration: time.Millisecond, - }) - if err != nil { - t.Fatalf("Set: %v", err) - } - - if err := c.Get(ctx, key, nil); err != ErrCacheMiss { - t.Errorf("GetBytes: got %v, want ErrCacheMiss", err) - } -}