Compare commits
15 Commits
master
...
release-br
Author | SHA1 | Date |
---|---|---|
|
e7e52e73e2 | |
|
156d532d4f | |
|
8cc6a32d9b | |
|
0d7f9d6ece | |
|
be728107ea | |
|
d1fff0794f | |
|
42933c415e | |
|
e9928cbe4a | |
|
d3e4ceb59d | |
|
97530abbb5 | |
|
bd7f39a7ac | |
|
27eedfbdea | |
|
1396c68d3b | |
|
c1ca329f65 | |
|
4c772e4117 |
|
@ -154,19 +154,32 @@ func waitForServerReady(t *testing.T, addr string) {
|
|||
waitForServer(t,
|
||||
fmt.Sprintf("http://%v/", addr),
|
||||
"The Go Programming Language",
|
||||
15*time.Second)
|
||||
15*time.Second,
|
||||
false)
|
||||
}
|
||||
|
||||
func waitForSearchReady(t *testing.T, addr string) {
|
||||
waitForServer(t,
|
||||
fmt.Sprintf("http://%v/search?q=FALLTHROUGH", addr),
|
||||
"The list of tokens.",
|
||||
2*time.Minute)
|
||||
2*time.Minute,
|
||||
false)
|
||||
}
|
||||
|
||||
func waitUntilScanComplete(t *testing.T, addr string) {
|
||||
waitForServer(t,
|
||||
fmt.Sprintf("http://%v/pkg", addr),
|
||||
"Scan is not yet complete",
|
||||
2*time.Minute,
|
||||
true,
|
||||
)
|
||||
// setting reverse as true, which means this waits
|
||||
// until the string is not returned in the response anymore
|
||||
}
|
||||
|
||||
const pollInterval = 200 * time.Millisecond
|
||||
|
||||
func waitForServer(t *testing.T, url, match string, timeout time.Duration) {
|
||||
func waitForServer(t *testing.T, url, match string, timeout time.Duration, reverse bool) {
|
||||
// "health check" duplicated from x/tools/cmd/tipgodoc/tip.go
|
||||
deadline := time.Now().Add(timeout)
|
||||
for time.Now().Before(deadline) {
|
||||
|
@ -177,9 +190,13 @@ func waitForServer(t *testing.T, url, match string, timeout time.Duration) {
|
|||
}
|
||||
rbody, err := ioutil.ReadAll(res.Body)
|
||||
res.Body.Close()
|
||||
if err == nil && res.StatusCode == http.StatusOK &&
|
||||
bytes.Contains(rbody, []byte(match)) {
|
||||
return
|
||||
if err == nil && res.StatusCode == http.StatusOK {
|
||||
if bytes.Contains(rbody, []byte(match)) && !reverse {
|
||||
return
|
||||
}
|
||||
if !bytes.Contains(rbody, []byte(match)) && reverse {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Fatalf("Server failed to respond in %v", timeout)
|
||||
|
@ -219,7 +236,12 @@ func testWeb(t *testing.T, withIndex bool) {
|
|||
cmd.Stdout = os.Stderr
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Args[0] = "godoc"
|
||||
cmd.Env = godocEnv()
|
||||
|
||||
// Set GOPATH variable to non-existing path.
|
||||
// We cannot just unset GOPATH variable because godoc would default it to ~/go.
|
||||
// (We don't want the indexer looking at the local workspace during tests.)
|
||||
cmd.Env = append(os.Environ(), "GOPATH=does_not_exist")
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatalf("failed to start godoc: %s", err)
|
||||
}
|
||||
|
@ -229,6 +251,7 @@ func testWeb(t *testing.T, withIndex bool) {
|
|||
waitForSearchReady(t, addr)
|
||||
} else {
|
||||
waitForServerReady(t, addr)
|
||||
waitUntilScanComplete(t, addr)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -372,14 +395,9 @@ func main() { print(lib.V) }
|
|||
defer cleanup()
|
||||
addr := serverAddress(t)
|
||||
cmd := exec.Command(bin, fmt.Sprintf("-http=%s", addr), "-analysis=type")
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("GOROOT=%s", filepath.Join(tmpdir, "goroot")))
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%s", filepath.Join(tmpdir, "gopath")))
|
||||
for _, e := range os.Environ() {
|
||||
if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") {
|
||||
continue
|
||||
}
|
||||
cmd.Env = append(cmd.Env, e)
|
||||
}
|
||||
cmd.Stdout = os.Stderr
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
|
@ -457,15 +475,3 @@ tryagain:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// godocEnv returns the process environment without the GOPATH variable.
|
||||
// (We don't want the indexer looking at the local workspace during tests.)
|
||||
func godocEnv() (env []string) {
|
||||
for _, v := range os.Environ() {
|
||||
if strings.HasPrefix(v, "GOPATH=") {
|
||||
continue
|
||||
}
|
||||
env = append(env, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ func main() {
|
|||
|
||||
// Start http server.
|
||||
if *verbose {
|
||||
log.Println("starting http server")
|
||||
log.Println("starting HTTP server")
|
||||
}
|
||||
if err := http.ListenAndServe(*httpAddr, handler); err != nil {
|
||||
log.Fatalf("ListenAndServe %s: %v", *httpAddr, err)
|
||||
|
|
|
@ -32,6 +32,7 @@ var xMap = map[string]xRepo{
|
|||
"debug": {"https://go.googlesource.com/debug", "git"},
|
||||
"exp": {"https://go.googlesource.com/exp", "git"},
|
||||
"image": {"https://go.googlesource.com/image", "git"},
|
||||
"lint": {"https://go.googlesource.com/lint", "git"},
|
||||
"mobile": {"https://go.googlesource.com/mobile", "git"},
|
||||
"net": {"https://go.googlesource.com/net", "git"},
|
||||
"oauth2": {"https://go.googlesource.com/oauth2", "git"},
|
||||
|
@ -46,6 +47,7 @@ var xMap = map[string]xRepo{
|
|||
"time": {"https://go.googlesource.com/time", "git"},
|
||||
"tools": {"https://go.googlesource.com/tools", "git"},
|
||||
"tour": {"https://go.googlesource.com/tour", "git"},
|
||||
"vgo": {"https://go.googlesource.com/vgo", "git"},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -56,5 +56,5 @@ references to field f int
|
|||
|
||||
-------- @referrers ref-type-U --------
|
||||
references to type U int
|
||||
open testdata/src/referrers/nosuchfile.y: no such file or directory (+ 1 more refs in this file)
|
||||
open nosuchfile.y: no such file or directory (+ 1 more refs in this file)
|
||||
|
||||
|
|
100
godoc/dl/dl.go
100
godoc/dl/dl.go
|
@ -16,6 +16,7 @@ import (
|
|||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -27,7 +28,6 @@ import (
|
|||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/datastore"
|
||||
"google.golang.org/appengine/log"
|
||||
|
@ -41,22 +41,24 @@ const (
|
|||
)
|
||||
|
||||
func RegisterHandlers(mux *http.ServeMux) {
|
||||
mux.Handle("/dl", http.RedirectHandler("/dl/", http.StatusFound))
|
||||
mux.HandleFunc("/dl", getHandler)
|
||||
mux.HandleFunc("/dl/", getHandler) // also serves listHandler
|
||||
mux.HandleFunc("/dl/upload", uploadHandler)
|
||||
mux.HandleFunc("/dl/init", initHandler)
|
||||
}
|
||||
|
||||
// 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
|
||||
OS string
|
||||
Arch string
|
||||
Version string
|
||||
Checksum string `datastore:",noindex"` // SHA1; deprecated
|
||||
ChecksumSHA256 string `datastore:",noindex"`
|
||||
Size int64 `datastore:",noindex"`
|
||||
Kind string // "archive", "installer", "source"
|
||||
Uploaded time.Time
|
||||
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 {
|
||||
|
@ -137,11 +139,11 @@ func (f File) URL() string {
|
|||
}
|
||||
|
||||
type Release struct {
|
||||
Version string
|
||||
Stable bool
|
||||
Files []File
|
||||
Visible bool // show files on page load
|
||||
SplitPortTable bool // whether files should be split by primary/other ports.
|
||||
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 {
|
||||
|
@ -159,12 +161,12 @@ type Feature struct {
|
|||
var featuredFiles = []Feature{
|
||||
{
|
||||
Platform: "Microsoft Windows",
|
||||
Requirements: "Windows XP SP3 or later, Intel 64-bit processor",
|
||||
Requirements: "Windows 7 or later, Intel 64-bit processor",
|
||||
fileRE: regexp.MustCompile(`\.windows-amd64\.msi$`),
|
||||
},
|
||||
{
|
||||
Platform: "Apple macOS",
|
||||
Requirements: "macOS 10.8 or later, Intel 64-bit processor",
|
||||
Requirements: "macOS 10.10 or later, Intel 64-bit processor",
|
||||
fileRE: regexp.MustCompile(`\.darwin-amd64(-osx10\.8)?\.pkg$`),
|
||||
},
|
||||
{
|
||||
|
@ -221,6 +223,17 @@ func listHandler(w http.ResponseWriter, r *http.Request) {
|
|||
log.Errorf(c, "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.Errorf(c, "failed rendering JSON for releases: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := listTemplate.ExecuteTemplate(w, "root", d); err != nil {
|
||||
log.Errorf(c, "error executing template: %v", err)
|
||||
}
|
||||
|
@ -415,21 +428,59 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func getHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// For go get golang.org/dl/go1.x.y, we need to serve the
|
||||
// same meta tags at /dl for cmd/go to validate against /dl/go1.x.y:
|
||||
if r.URL.Path == "/dl" && (r.Method == "GET" || r.Method == "HEAD") && r.FormValue("go-get") == "1" {
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
fmt.Fprintf(w, `<!DOCTYPE html><html><head>
|
||||
<meta name="go-import" content="golang.org/dl git https://go.googlesource.com/dl">
|
||||
</head></html>`)
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/dl" {
|
||||
http.Redirect(w, r, "/dl/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
name := strings.TrimPrefix(r.URL.Path, "/dl/")
|
||||
if name == "" {
|
||||
listHandler(w, r)
|
||||
return
|
||||
}
|
||||
if !fileRe.MatchString(name) {
|
||||
http.NotFound(w, r)
|
||||
if fileRe.MatchString(name) {
|
||||
http.Redirect(w, r, downloadBaseURL+name, http.StatusFound)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, downloadBaseURL+name, http.StatusFound)
|
||||
if goGetRe.MatchString(name) {
|
||||
var isGoGet bool
|
||||
if r.Method == "GET" || r.Method == "HEAD" {
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
isGoGet = r.FormValue("go-get") == "1"
|
||||
}
|
||||
if !isGoGet {
|
||||
w.Header().Set("Location", "https://golang.org/dl/#"+name)
|
||||
w.WriteHeader(http.StatusFound)
|
||||
}
|
||||
fmt.Fprintf(w, `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta name="go-import" content="golang.org/dl git https://go.googlesource.com/dl">
|
||||
<meta http-equiv="refresh" content="0; url=https://golang.org/dl/#%s">
|
||||
</head>
|
||||
<body>
|
||||
Nothing to see here; <a href="https://golang.org/dl/#%s">move along</a>.
|
||||
</body>
|
||||
</html>
|
||||
`, html.EscapeString(name), html.EscapeString(name))
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
func validUser(user string) bool {
|
||||
switch user {
|
||||
case "adg", "bradfitz", "cbro", "andybons":
|
||||
case "adg", "bradfitz", "cbro", "andybons", "valsorda":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -441,7 +492,10 @@ func userKey(c context.Context, user string) string {
|
|||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
var fileRe = regexp.MustCompile(`^go[0-9a-z.]+\.[0-9a-z.-]+\.(tar\.gz|pkg|msi|zip)$`)
|
||||
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.-]+$`)
|
||||
)
|
||||
|
||||
func initHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var fileRoot struct {
|
||||
|
|
|
@ -220,7 +220,7 @@ $(document).ready(function() {
|
|||
<p>This is an <b>unstable</b> version of Go. Use with caution.</p>
|
||||
<p>If you already have Go installed, you can install this version by running:</p>
|
||||
<pre>
|
||||
go get golang.org/x/build/version/{{.Version}}
|
||||
go get golang.org/dl/{{.Version}}
|
||||
</pre>
|
||||
<p>Then, use the <code>{{.Version}}</code> command instead of the <code>go</code> command to use {{.Version}}.</p>
|
||||
{{end}}
|
||||
|
|
|
@ -253,13 +253,13 @@ function personalizeInstallInstructions() {
|
|||
|
||||
var filename = s.substr(prefix.length);
|
||||
var filenameRE = /^go1\.\d+(\.\d+)?([a-z0-9]+)?\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\.[68])?\.([a-z.]+)$/;
|
||||
$('.downloadFilename').text(filename);
|
||||
$('.hideFromDownload').hide();
|
||||
var m = filenameRE.exec(filename);
|
||||
if (!m) {
|
||||
// Can't interpret file name; bail.
|
||||
return;
|
||||
}
|
||||
$('.downloadFilename').text(filename);
|
||||
$('.hideFromDownload').hide();
|
||||
|
||||
var os = m[3];
|
||||
var ext = m[6];
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -90,7 +90,7 @@ func (p *Presentation) code(file string, arg ...interface{}) (s string, err erro
|
|||
command = fmt.Sprintf("code %q %s %s", file, stringFor(arg[0]), stringFor(arg[1]))
|
||||
text = p.Corpus.multipleLines(file, text, arg[0], arg[1])
|
||||
default:
|
||||
return "", fmt.Errorf("incorrect code invocation: code %q %q", file, arg)
|
||||
return "", fmt.Errorf("incorrect code invocation: code %q [%v, ...] (%d arguments)", file, arg[0], len(arg))
|
||||
}
|
||||
// Trim spaces from output.
|
||||
text = strings.Trim(text, "\n")
|
||||
|
|
Loading…
Reference in New Issue