// 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.

// Command release builds a Go release.
package main

import (
	"archive/tar"
	"archive/zip"
	"bufio"
	"bytes"
	"compress/gzip"
	"context"
	"flag"
	"fmt"
	gobuild "go/build"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"time"

	"golang.org/x/build"
	"golang.org/x/build/buildenv"
	"golang.org/x/build/buildlet"
	"golang.org/x/build/dashboard"
)

var (
	target = flag.String("target", "", "If specified, build specific target platform (e.g. 'linux-amd64'). Default is to build all.")
	watch  = flag.Bool("watch", false, "Watch the build. Only compatible with -target")

	rev       = flag.String("rev", "", "Go revision to build, alternative to -tarball")
	tarball   = flag.String("tarball", "", "Go tree tarball to build, alternative to -rev")
	toolsRev  = flag.String("tools", "", "Tools revision to build")
	tourRev   = flag.String("tour", "master", "Tour revision to include")
	netRev    = flag.String("net", "master", "Net revision to include")
	version   = flag.String("version", "", "Version string (go1.5.2)")
	user      = flag.String("user", username(), "coordinator username, appended to 'user-'")
	skipTests = flag.Bool("skip_tests", false, "skip tests; run make.bash instead of all.bash (only use if you ran trybots first)")

	uploadMode = flag.Bool("upload", false, "Upload files (exclusive to all other flags)")
	uploadKick = flag.String("edge_kick_command", "", "Command to run to kick off an edge cache update")
)

var (
	coordClient *buildlet.CoordinatorClient
	buildEnv    *buildenv.Environment
)

func main() {
	flag.Parse()
	rand.Seed(time.Now().UnixNano())

	if *uploadMode {
		buildenv.CheckUserCredentials()
		if err := upload(flag.Args()); err != nil {
			log.Fatal(err)
		}
		return
	}

	if err := findReleaselet(); err != nil {
		log.Fatalf("couldn't find releaselet source: %v", err)
	}

	if (*rev == "" && *tarball == "") || (*rev != "" && *tarball != "") {
		log.Fatal("must specify one of -rev or -tarball")
	}
	if *version == "" {
		log.Fatal(`must specify -version flag (such as "go1.12" or "go1.13beta1")`)
	}
	if *toolsRev == "" && (versionIncludesGodoc(*version) || versionIncludesTour(*version)) {
		log.Fatal("must specify -tools flag")
	}

	coordClient = coordinatorClient()
	buildEnv = buildenv.Production

	var wg sync.WaitGroup
	matches := 0
	for _, b := range builds {
		b := b
		if *target != "" && b.String() != *target {
			continue
		}
		matches++
		b.logf("Start.")
		wg.Add(1)
		go func() {
			defer wg.Done()
			if err := b.make(); err != nil {
				b.logf("Error: %v", err)
			} else {
				b.logf("Done.")
			}
		}()
	}
	if *target != "" && matches == 0 {
		log.Fatalf("no targets matched %q", *target)
	}
	wg.Wait()
}

var releaselet = "releaselet.go"

func findReleaselet() error {
	// First try the working directory.
	if _, err := os.Stat(releaselet); err == nil {
		return nil
	}

	// Then, try to locate the release command in the workspace.
	const importPath = "golang.org/x/build/cmd/release"
	pkg, err := gobuild.Import(importPath, "", gobuild.FindOnly)
	if err != nil {
		return fmt.Errorf("finding %q: %v", importPath, err)
	}
	r := filepath.Join(pkg.Dir, releaselet)
	if _, err := os.Stat(r); err != nil {
		return err
	}
	releaselet = r
	return nil
}

type Build struct {
	OS, Arch string
	Source   bool

	Race bool // Build race detector.

	Builder string // Key for dashboard.Builders.

	Goarm    int  // GOARM value if set.
	MakeOnly bool // don't run tests; needed by cross-compile builders (s390x)
}

func (b *Build) String() string {
	if b.Source {
		return "src"
	}
	if b.Goarm != 0 {
		return fmt.Sprintf("%v-%vv%vl", b.OS, b.Arch, b.Goarm)
	}
	return fmt.Sprintf("%v-%v", b.OS, b.Arch)
}

func (b *Build) toolDir() string { return "go/pkg/tool/" + b.OS + "_" + b.Arch }
func (b *Build) pkgDir() string  { return "go/pkg/" + b.OS + "_" + b.Arch }

func (b *Build) logf(format string, args ...interface{}) {
	format = fmt.Sprintf("%v: %s", b, format)
	log.Printf(format, args...)
}

var builds = []*Build{
	{
		Source:  true,
		Builder: "linux-amd64",
	},
	{
		OS:      "linux",
		Arch:    "386",
		Builder: "linux-386",
	},
	{
		OS:      "linux",
		Arch:    "arm",
		Builder: "linux-arm",
		Goarm:   6, // for compatibility with all Raspberry Pi models.
		// The tests take too long for the release packaging.
		// Much of the time the whole buildlet times out.
		MakeOnly: true,
	},
	{
		OS:      "linux",
		Arch:    "amd64",
		Race:    true,
		Builder: "linux-amd64-jessie", // using Jessie for at least [Go 1.11, Go 1.13] due to golang.org/issue/31336
	},
	{
		OS:      "linux",
		Arch:    "arm64",
		Builder: "linux-arm64-packet",
	},
	{
		OS:      "freebsd",
		Arch:    "386",
		Builder: "freebsd-386-11_1",
	},
	{
		OS:      "freebsd",
		Arch:    "amd64",
		Race:    true,
		Builder: "freebsd-amd64-11_1",
	},
	{
		OS:      "windows",
		Arch:    "386",
		Builder: "windows-386-2008",
	},
	{
		OS:      "windows",
		Arch:    "amd64",
		Race:    true,
		Builder: "windows-amd64-2008",
	},
	{
		OS:      "darwin",
		Arch:    "amd64",
		Race:    true,
		Builder: "darwin-amd64-10_11",
	},
	{
		OS:       "linux",
		Arch:     "s390x",
		MakeOnly: true,
		Builder:  "linux-s390x-crosscompile",
	},
	// TODO(bradfitz): switch this ppc64 builder to a Kubernetes
	// container cross-compiling ppc64 like the s390x one? For
	// now, the ppc64le builders (5) are back, so let's see if we
	// can just depend on them not going away.
	{
		OS:       "linux",
		Arch:     "ppc64le",
		MakeOnly: true,
		Builder:  "linux-ppc64le-buildlet",
	},
}

var preBuildCleanFiles = []string{
	".gitattributes",
	".github",
	".gitignore",
	".hgignore",
	".hgtags",
	"misc/dashboard",
	"misc/makerelease",
}

func (b *Build) buildlet() (*buildlet.Client, error) {
	b.logf("Creating buildlet.")
	bc, err := coordClient.CreateBuildlet(b.Builder)
	if err != nil {
		return nil, err
	}
	bc.SetReleaseMode(true) // disable pargzip; golang.org/issue/19052
	return bc, nil
}

func (b *Build) make() error {
	bc, ok := dashboard.Builders[b.Builder]
	if !ok {
		return fmt.Errorf("unknown builder: %v", bc)
	}

	var hostArch string // non-empty if we're cross-compiling (s390x)
	if b.MakeOnly && bc.IsContainer() && (bc.GOARCH() != "amd64" && bc.GOARCH() != "386") {
		hostArch = "amd64"
	}

	client, err := b.buildlet()
	if err != nil {
		return err
	}
	defer client.Close()

	work, err := client.WorkDir()
	if err != nil {
		return err
	}

	// Push source to buildlet
	b.logf("Pushing source to buildlet.")
	const (
		goDir  = "go"
		goPath = "gopath"
		go14   = "go1.4"
	)
	if *tarball != "" {
		tarFile, err := os.Open(*tarball)
		if err != nil {
			b.logf("failed to open tarball %q: %v", *tarball, err)
			return err
		}
		if err := client.PutTar(tarFile, goDir); err != nil {
			b.logf("failed to put tarball %q into dir %q: %v", *tarball, goDir, err)
			return err
		}
		tarFile.Close()
	} else {
		tar := "https://go.googlesource.com/go/+archive/" + *rev + ".tar.gz"
		if err := client.PutTarFromURL(tar, goDir); err != nil {
			b.logf("failed to put tarball %q into dir %q: %v", tar, goDir, err)
			return err
		}
	}
	for _, r := range []struct {
		repo, rev string
	}{
		{"tools", *toolsRev},
		{"tour", *tourRev},
		{"net", *netRev},
	} {
		if b.Source {
			continue
		}
		if r.repo == "tour" && !versionIncludesTour(*version) {
			continue
		}
		if (r.repo == "net" || r.repo == "tools") && !versionIncludesGodoc(*version) {
			continue
		}
		dir := goPath + "/src/golang.org/x/" + r.repo
		tar := "https://go.googlesource.com/" + r.repo + "/+archive/" + r.rev + ".tar.gz"
		if err := client.PutTarFromURL(tar, dir); err != nil {
			b.logf("failed to put tarball %q into dir %q: %v", tar, dir, err)
			return err
		}
	}

	if u := bc.GoBootstrapURL(buildEnv); u != "" && !b.Source {
		b.logf("Installing go1.4.")
		if err := client.PutTarFromURL(u, go14); err != nil {
			return err
		}
	}

	// Write out version file.
	b.logf("Writing VERSION file.")
	if err := client.Put(strings.NewReader(*version), "go/VERSION", 0644); err != nil {
		return err
	}

	b.logf("Cleaning goroot (pre-build).")
	if err := client.RemoveAll(addPrefix(goDir, preBuildCleanFiles)...); err != nil {
		return err
	}

	if b.Source {
		b.logf("Skipping build.")

		// Remove unwanted top-level directories and verify only "go" remains:
		if err := client.RemoveAll("tmp", "gocache"); err != nil {
			return err
		}
		if err := b.checkTopLevelDirs(client); err != nil {
			return fmt.Errorf("verifying no unwanted top-level directories: %v", err)
		}

		return b.fetchTarball(client)
	}

	// Set up build environment.
	sep := "/"
	if b.OS == "windows" {
		sep = "\\"
	}
	env := append(bc.Env(),
		"GOROOT_FINAL="+bc.GorootFinal(),
		"GOROOT="+work+sep+goDir,
		"GOPATH="+work+sep+goPath,
		"GOBIN=",
	)

	if b.Goarm > 0 {
		env = append(env, fmt.Sprintf("GOARM=%d", b.Goarm))
		env = append(env, fmt.Sprintf("CGO_CFLAGS=-march=armv%d", b.Goarm))
		env = append(env, fmt.Sprintf("CGO_LDFLAGS=-march=armv%d", b.Goarm))
	}

	// Execute build
	b.logf("Building.")
	out := new(bytes.Buffer)
	script := bc.AllScript()
	scriptArgs := bc.AllScriptArgs()
	if *skipTests || b.MakeOnly {
		script = bc.MakeScript()
		scriptArgs = bc.MakeScriptArgs()
	}
	all := filepath.Join(goDir, script)
	var execOut io.Writer = out
	if *watch && *target != "" {
		execOut = io.MultiWriter(out, os.Stdout)
	}
	remoteErr, err := client.Exec(all, buildlet.ExecOpts{
		Output:   execOut,
		ExtraEnv: env,
		Args:     scriptArgs,
	})
	if err != nil {
		return err
	}
	if remoteErr != nil {
		return fmt.Errorf("Build failed: %v\nOutput:\n%v", remoteErr, out)
	}

	if err := b.checkRelocations(client); err != nil {
		return err
	}

	goCmd := path.Join(goDir, "bin/go")
	if b.OS == "windows" {
		goCmd += ".exe"
	}
	runGo := func(args ...string) error {
		out := new(bytes.Buffer)
		var execOut io.Writer = out
		if *watch && *target != "" {
			execOut = io.MultiWriter(out, os.Stdout)
		}
		cmdEnv := append([]string(nil), env...)
		if len(args) > 0 && args[0] == "run" && hostArch != "" {
			cmdEnv = setGOARCH(cmdEnv, hostArch)
		}
		remoteErr, err := client.Exec(goCmd, buildlet.ExecOpts{
			Output:   execOut,
			Dir:      ".", // root of buildlet work directory
			Args:     args,
			ExtraEnv: cmdEnv,
		})
		if err != nil {
			return err
		}
		if remoteErr != nil {
			return fmt.Errorf("go %v: %v\n%s", strings.Join(args, " "), remoteErr, out)
		}
		return nil
	}

	if b.Race {
		b.logf("Building race detector.")

		if err := runGo("install", "-race", "std"); err != nil {
			return err
		}
	}

	var toolPaths []string
	if versionIncludesGodoc(*version) {
		toolPaths = append(toolPaths, "golang.org/x/tools/cmd/godoc")
	}
	if versionIncludesTour(*version) {
		toolPaths = append(toolPaths, "golang.org/x/tour")
	}
	if len(toolPaths) > 0 {
		b.logf("Building %v.", strings.Join(toolPaths, ", "))
		if err := runGo(append([]string{"install"}, toolPaths...)...); err != nil {
			return err
		}
	}

	// postBuildCleanFiles are the list of files to remove in the go/ directory
	// after things have been built.
	postBuildCleanFiles := []string{
		"VERSION.cache",
		"pkg/bootstrap",
	}

	// Remove race detector *.syso files for other GOOS/GOARCHes (except for the source release).
	if !b.Source {
		okayRace := fmt.Sprintf("race_%s_%s.syso", b.OS, b.Arch)
		err := client.ListDir(".", buildlet.ListDirOpts{Recursive: true}, func(ent buildlet.DirEntry) {
			name := strings.TrimPrefix(ent.Name(), "go/")
			if strings.HasPrefix(name, "src/runtime/race/race_") &&
				strings.HasSuffix(name, ".syso") &&
				path.Base(name) != okayRace {
				postBuildCleanFiles = append(postBuildCleanFiles, name)
			}
		})
		if err != nil {
			return fmt.Errorf("enumerating files to clean race syso files: %v", err)
		}
	}

	b.logf("Cleaning goroot (post-build).")
	if err := client.RemoveAll(addPrefix(goDir, postBuildCleanFiles)...); err != nil {
		return err
	}
	// Users don't need the api checker binary pre-built. It's
	// used by tests, but all.bash builds it first.
	if err := client.RemoveAll(b.toolDir() + "/api"); err != nil {
		return err
	}
	// Remove go/pkg/${GOOS}_${GOARCH}/cmd. This saves a bunch of
	// space, and users don't typically rebuild cmd/compile,
	// cmd/link, etc. If they want to, they still can, but they'll
	// have to pay the cost of rebuilding dependent libaries. No
	// need to ship them just in case.
	//
	// Also remove go/pkg/${GOOS}_${GOARCH}_{dynlink,shared,testcshared_shared}
	// per Issue 20038.
	if err := client.RemoveAll(
		b.pkgDir()+"/cmd",
		b.pkgDir()+"_dynlink",
		b.pkgDir()+"_shared",
		b.pkgDir()+"_testcshared_shared",
	); err != nil {
		return err
	}

	b.logf("Pushing and running releaselet.")
	f, err := os.Open(releaselet)
	if err != nil {
		return err
	}
	err = client.Put(f, "releaselet.go", 0666)
	f.Close()
	if err != nil {
		return err
	}
	if err := runGo("run", "releaselet.go"); err != nil {
		log.Printf("releaselet failed: %v", err)
		client.ListDir(".", buildlet.ListDirOpts{Recursive: true}, func(ent buildlet.DirEntry) {
			log.Printf("remote: %v", ent)
		})
		return err
	}

	cleanFiles := []string{"releaselet.go", goPath, go14, "tmp", "gocache"}

	switch b.OS {
	case "darwin":
		filename := *version + "." + b.String() + ".pkg"
		if err := b.fetchFile(client, filename, "pkg"); err != nil {
			return err
		}
		cleanFiles = append(cleanFiles, "pkg")
	case "windows":
		filename := *version + "." + b.String() + ".msi"
		if err := b.fetchFile(client, filename, "msi"); err != nil {
			return err
		}
		cleanFiles = append(cleanFiles, "msi")
	}

	// Need to delete everything except the final "go" directory,
	// as we make the tarball relative to workdir.
	b.logf("Cleaning workdir.")
	if err := client.RemoveAll(cleanFiles...); err != nil {
		return err
	}

	// And verify there's no other top-level stuff besides the "go" directory:
	if err := b.checkTopLevelDirs(client); err != nil {
		return fmt.Errorf("verifying no unwanted top-level directories: %v", err)
	}

	if b.OS == "windows" {
		return b.fetchZip(client)
	}
	return b.fetchTarball(client)
}

// checkTopLevelDirs checks that all files under client's "."
// ($WORKDIR) are are under "go/".
func (b *Build) checkTopLevelDirs(client *buildlet.Client) error {
	var badFileErr error // non-nil once an unexpected file/dir is found
	if err := client.ListDir(".", buildlet.ListDirOpts{Recursive: true}, func(ent buildlet.DirEntry) {
		name := ent.Name()
		if !(strings.HasPrefix(name, "go/") || strings.HasPrefix(name, `go\`)) {
			b.logf("unexpected file: %q", name)
			if badFileErr == nil {
				badFileErr = fmt.Errorf("unexpected filename %q found after cleaning", name)
			}
		}
	}); err != nil {
		return err
	}
	return badFileErr
}

func (b *Build) fetchTarball(client *buildlet.Client) error {
	b.logf("Downloading tarball.")
	tgz, err := client.GetTar(context.Background(), ".")
	if err != nil {
		return err
	}
	filename := *version + "." + b.String() + ".tar.gz"
	return b.writeFile(filename, tgz)
}

func (b *Build) fetchZip(client *buildlet.Client) error {
	b.logf("Downloading tarball and re-compressing as zip.")

	tgz, err := client.GetTar(context.Background(), ".")
	if err != nil {
		return err
	}
	defer tgz.Close()

	filename := *version + "." + b.String() + ".zip"
	f, err := os.Create(filename)
	if err != nil {
		return err
	}
	if err := tgzToZip(f, tgz); err != nil {
		f.Close()
		return err
	}
	if err := f.Close(); err != nil {
		return err
	}

	b.logf("Wrote %q.", filename)
	return nil
}

func tgzToZip(w io.Writer, r io.Reader) error {
	zr, err := gzip.NewReader(r)
	if err != nil {
		return err
	}
	tr := tar.NewReader(zr)

	zw := zip.NewWriter(w)
	for {
		th, err := tr.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
		fi := th.FileInfo()
		zh, err := zip.FileInfoHeader(fi)
		if err != nil {
			return err
		}
		zh.Name = th.Name // for the full path
		switch strings.ToLower(path.Ext(zh.Name)) {
		case ".jpg", ".jpeg", ".png", ".gif":
			// Don't re-compress already compressed files.
			zh.Method = zip.Store
		default:
			zh.Method = zip.Deflate
		}
		if fi.IsDir() {
			zh.Method = zip.Store
		}
		w, err := zw.CreateHeader(zh)
		if err != nil {
			return err
		}
		if fi.IsDir() {
			continue
		}
		if _, err := io.Copy(w, tr); err != nil {
			return err
		}
	}
	return zw.Close()
}

// fetchFile fetches the specified directory from the given buildlet, and
// writes the first file it finds in that directory to dest.
func (b *Build) fetchFile(client *buildlet.Client, dest, dir string) error {
	b.logf("Downloading file from %q.", dir)
	tgz, err := client.GetTar(context.Background(), dir)
	if err != nil {
		return err
	}
	defer tgz.Close()
	zr, err := gzip.NewReader(tgz)
	if err != nil {
		return err
	}
	tr := tar.NewReader(zr)
	for {
		h, err := tr.Next()
		if err == io.EOF {
			return io.ErrUnexpectedEOF
		}
		if err != nil {
			return err
		}
		if !h.FileInfo().IsDir() {
			break
		}
	}
	return b.writeFile(dest, tr)
}

func (b *Build) writeFile(name string, r io.Reader) error {
	f, err := os.Create(name)
	if err != nil {
		return err
	}
	if _, err := io.Copy(f, r); err != nil {
		f.Close()
		return err
	}
	if err := f.Close(); err != nil {
		return err
	}
	if strings.HasSuffix(name, ".gz") {
		if err := verifyGzipSingleStream(name); err != nil {
			return fmt.Errorf("error verifying that %s is a single-stream gzip: %v", name, err)
		}
	}
	b.logf("Wrote %q.", name)
	return nil
}

// checkRelocations runs readelf on pkg/linux_amd64/runtime/cgo.a and makes sure
// we don't see R_X86_64_REX_GOTPCRELX. See issue 31293.
func (b *Build) checkRelocations(client *buildlet.Client) error {
	if b.OS != "linux" || b.Arch != "amd64" {
		return nil
	}
	var out bytes.Buffer
	file := fmt.Sprintf("go/pkg/linux_%s/runtime/cgo.a", b.Arch)
	remoteErr, err := client.Exec("readelf", buildlet.ExecOpts{
		Output:      &out,
		Args:        []string{"-r", "--wide", file},
		SystemLevel: true, // look for readelf in system's PATH
	})
	if err != nil {
		return fmt.Errorf("failed to run readelf: %v", err)
	}
	got := out.String()
	if strings.Contains(got, "R_X86_64_REX_GOTPCRELX") {
		return fmt.Errorf("%s contained a R_X86_64_REX_GOTPCRELX relocation", file)
	}
	if !strings.Contains(got, "R_X86_64_GOTPCREL") {
		return fmt.Errorf("%s did not contain a R_X86_64_GOTPCREL relocation; remoteErr=%v, %s", file, remoteErr, got)
	}
	return nil
}

// verifyGzipSingleStream verifies that the named gzip file is not
// a multi-stream file. See golang.org/issue/19052
func verifyGzipSingleStream(name string) error {
	f, err := os.Open(name)
	if err != nil {
		return err
	}
	defer f.Close()
	br := bufio.NewReader(f)
	zr, err := gzip.NewReader(br)
	if err != nil {
		return err
	}
	zr.Multistream(false)
	if _, err := io.Copy(ioutil.Discard, zr); err != nil {
		return fmt.Errorf("reading first stream: %v", err)
	}
	peek, err := br.Peek(1)
	if len(peek) > 0 || err != io.EOF {
		return fmt.Errorf("unexpected peek of %d, %v after first gzip stream", len(peek), err)
	}
	return nil
}

func addPrefix(prefix string, in []string) []string {
	var out []string
	for _, s := range in {
		out = append(out, path.Join(prefix, s))
	}
	return out
}

func coordinatorClient() *buildlet.CoordinatorClient {
	return &buildlet.CoordinatorClient{
		Auth: buildlet.UserPass{
			Username: "user-" + *user,
			Password: userToken(),
		},
		Instance: build.ProdCoordinator,
	}
}

func homeDir() string {
	if runtime.GOOS == "windows" {
		return os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
	}
	return os.Getenv("HOME")
}

func configDir() string {
	if runtime.GOOS == "windows" {
		return filepath.Join(os.Getenv("APPDATA"), "Gomote")
	}
	if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" {
		return filepath.Join(xdg, "gomote")
	}
	return filepath.Join(homeDir(), ".config", "gomote")
}

func username() string {
	if runtime.GOOS == "windows" {
		return os.Getenv("USERNAME")
	}
	return os.Getenv("USER")
}

func userToken() string {
	if *user == "" {
		panic("userToken called with user flag empty")
	}
	keyDir := configDir()
	baseFile := "user-" + *user + ".token"
	tokenFile := filepath.Join(keyDir, baseFile)
	slurp, err := ioutil.ReadFile(tokenFile)
	if os.IsNotExist(err) {
		log.Printf("Missing file %s for user %q. Change --user or obtain a token and place it there.",
			tokenFile, *user)
	}
	if err != nil {
		log.Fatal(err)
	}
	return strings.TrimSpace(string(slurp))
}

func setGOARCH(env []string, goarch string) []string {
	wantKV := "GOARCH=" + goarch
	existing := false
	for i, kv := range env {
		if strings.HasPrefix(kv, "GOARCH=") && kv != wantKV {
			env[i] = wantKV
			existing = true
		}
	}
	if existing {
		return env
	}
	return append(env, wantKV)
}

// versionIncludesTour reports whether the provided Go version (of the
// form "go1.N" or "go1.N.M" includes the Go tour binary.
func versionIncludesTour(goVer string) bool {
	// We don't do releases of Go 1.9 and earlier, so this only
	// needs to recognize the two current past releases. From Go
	// 1.12 and on, we won't ship the tour binary (see CL 131156).
	return strings.HasPrefix(goVer, "go1.10.") ||
		strings.HasPrefix(goVer, "go1.11.")
}

// versionIncludesGodoc reports whether the provided Go version (of the
// form "go1.N" or "go1.N.M" includes the godoc binary.
func versionIncludesGodoc(goVer string) bool {
	// We don't do releases of Go 1.10 and earlier, so this only
	// needs to recognize the two current past releases. From Go
	// 1.13 and on, we won't ship the godoc binary (see Issue 30029).
	return strings.HasPrefix(goVer, "go1.11.") ||
		strings.HasPrefix(goVer, "go1.12.")
}
