dmitri.shuralyov.com/website/gido/...

determine directories by walking Go repositories

Fetch to memory the latest commit of "master", "release-branch.go1.12",
"release-branch.go1.11" branches of all relevant Go repositories, and
then walk their trees to collect the list of directories. This scales
better than manually maintaining a list of Go packages.

For now, this is only done once at process start, and the release
branch names are hardcoded. This can be improved later.

Also add dl, example, mod, website, and xerrors sub-repositories.

Updates https://dmitri.shuralyov.com/website/gido/...$issues/3.
dmitshur committed 5 years ago commit 5275a64acd14885a8d67315e2b66570347b757af
Collapse all
main.go
@@ -59,10 +59,12 @@ func main() {
		log.Fatalln(err)
	}
}

func run(ctx context.Context, router Router, analyticsFile string) error {
	log.Println("Starting.")

	if err := mime.AddExtensionType(".woff2", "font/woff2"); err != nil {
		return err
	}

	var analyticsHTML []byte
@@ -72,10 +74,15 @@ func run(ctx context.Context, router Router, analyticsFile string) error {
		if err != nil {
			return err
		}
	}

	err := initExistingDirectories()
	if err != nil {
		return err
	}

	server := &http.Server{Addr: *httpFlag, Handler: top{gzipHandler{&errorHandler{handler: (&handler{
		rtr:           router,
		analyticsHTML: template.HTML(analyticsHTML),
		fontsHandler:  httpgzip.FileServer(assets.Fonts, httpgzip.FileServerOptions{ServeError: httpgzip.Detailed}),
		assetsHandler: httpgzip.FileServer(assets.Assets, httpgzip.FileServerOptions{ServeError: httpgzip.Detailed}),
@@ -90,11 +97,11 @@ func run(ctx context.Context, router Router, analyticsFile string) error {
		}
	}()

	log.Println("Starting HTTP server.")

	err := server.ListenAndServe()
	err = server.ListenAndServe()
	if err != http.ErrServerClosed {
		log.Println("server.ListenAndServe:", err)
	}

	log.Println("Ended HTTP server.")
packages.go
@@ -1,981 +1,131 @@
package main

import (
	"errors"
	"fmt"
	"os"
	"path"
	"regexp"
	"strings"

	"gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/filemode"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
	"gopkg.in/src-d/go-git.v4/storage/memory"
)

// TODO: Consider including directories from GOROOT other than just packages in GOROOT/src.
// TODO: Consider including special prefixes such as "all:", "build:", "gccgo:", "website:", "wiki:", etc.

// existingPackages is a set of import paths of Go packages that are known to exist.
// It includes packages in Go standard library and sub-repositories.
//
// The list is generated with:
//
// 	cat <(GOOS=linux go list std cmd golang.org/x/...) \
// 	    <(GOOS=darwin go list std cmd golang.org/x/...) \
// 	    <(GOOS=windows go list std cmd golang.org/x/...) \
// 	    | sort | uniq
//
var existingPackages = map[string]struct{}{
	"archive/tar":                               {},
	"archive/zip":                               {},
	"bufio":                                     {},
	"bytes":                                     {},
	"cmd/addr2line":                             {},
	"cmd/api":                                   {},
	"cmd/asm":                                   {},
	"cmd/asm/internal/arch":                     {},
	"cmd/asm/internal/asm":                      {},
	"cmd/asm/internal/flags":                    {},
	"cmd/asm/internal/lex":                      {},
	"cmd/buildid":                               {},
	"cmd/cgo":                                   {},
	"cmd/compile":                               {},
	"cmd/compile/internal/amd64":                {},
	"cmd/compile/internal/arm":                  {},
	"cmd/compile/internal/arm64":                {},
	"cmd/compile/internal/gc":                   {},
	"cmd/compile/internal/mips":                 {},
	"cmd/compile/internal/mips64":               {},
	"cmd/compile/internal/ppc64":                {},
	"cmd/compile/internal/s390x":                {},
	"cmd/compile/internal/ssa":                  {},
	"cmd/compile/internal/syntax":               {},
	"cmd/compile/internal/test":                 {},
	"cmd/compile/internal/types":                {},
	"cmd/compile/internal/wasm":                 {},
	"cmd/compile/internal/x86":                  {},
	"cmd/cover":                                 {},
	"cmd/dist":                                  {},
	"cmd/doc":                                   {},
	"cmd/fix":                                   {},
	"cmd/go":                                    {},
	"cmd/go/internal/base":                      {},
	"cmd/go/internal/bug":                       {},
	"cmd/go/internal/cache":                     {},
	"cmd/go/internal/cfg":                       {},
	"cmd/go/internal/clean":                     {},
	"cmd/go/internal/cmdflag":                   {},
	"cmd/go/internal/dirhash":                   {},
	"cmd/go/internal/doc":                       {},
	"cmd/go/internal/envcmd":                    {},
	"cmd/go/internal/fix":                       {},
	"cmd/go/internal/fmtcmd":                    {},
	"cmd/go/internal/generate":                  {},
	"cmd/go/internal/get":                       {},
	"cmd/go/internal/help":                      {},
	"cmd/go/internal/imports":                   {},
	"cmd/go/internal/list":                      {},
	"cmd/go/internal/load":                      {},
	"cmd/go/internal/modcmd":                    {},
	"cmd/go/internal/modconv":                   {},
	"cmd/go/internal/modfetch":                  {},
	"cmd/go/internal/modfetch/codehost":         {},
	"cmd/go/internal/modfile":                   {},
	"cmd/go/internal/modget":                    {},
	"cmd/go/internal/modinfo":                   {},
	"cmd/go/internal/modload":                   {},
	"cmd/go/internal/module":                    {},
	"cmd/go/internal/mvs":                       {},
	"cmd/go/internal/par":                       {},
	"cmd/go/internal/run":                       {},
	"cmd/go/internal/search":                    {},
	"cmd/go/internal/semver":                    {},
	"cmd/go/internal/str":                       {},
	"cmd/go/internal/test":                      {},
	"cmd/go/internal/tool":                      {},
	"cmd/go/internal/txtar":                     {},
	"cmd/go/internal/version":                   {},
	"cmd/go/internal/vet":                       {},
	"cmd/go/internal/web":                       {},
	"cmd/go/internal/web2":                      {},
	"cmd/go/internal/webtest":                   {},
	"cmd/go/internal/work":                      {},
	"cmd/gofmt":                                 {},
	"cmd/internal/bio":                          {},
	"cmd/internal/browser":                      {},
	"cmd/internal/buildid":                      {},
	"cmd/internal/dwarf":                        {},
	"cmd/internal/edit":                         {},
	"cmd/internal/gcprog":                       {},
	"cmd/internal/goobj":                        {},
	"cmd/internal/obj":                          {},
	"cmd/internal/obj/arm":                      {},
	"cmd/internal/obj/arm64":                    {},
	"cmd/internal/obj/mips":                     {},
	"cmd/internal/obj/ppc64":                    {},
	"cmd/internal/obj/s390x":                    {},
	"cmd/internal/obj/wasm":                     {},
	"cmd/internal/obj/x86":                      {},
	"cmd/internal/objabi":                       {},
	"cmd/internal/objfile":                      {},
	"cmd/internal/src":                          {},
	"cmd/internal/sys":                          {},
	"cmd/internal/test2json":                    {},
	"cmd/link":                                  {},
	"cmd/link/internal/amd64":                   {},
	"cmd/link/internal/arm":                     {},
	"cmd/link/internal/arm64":                   {},
	"cmd/link/internal/ld":                      {},
	"cmd/link/internal/loadelf":                 {},
	"cmd/link/internal/loadmacho":               {},
	"cmd/link/internal/loadpe":                  {},
	"cmd/link/internal/mips":                    {},
	"cmd/link/internal/mips64":                  {},
	"cmd/link/internal/objfile":                 {},
	"cmd/link/internal/ppc64":                   {},
	"cmd/link/internal/s390x":                   {},
	"cmd/link/internal/sym":                     {},
	"cmd/link/internal/wasm":                    {},
	"cmd/link/internal/x86":                     {},
	"cmd/nm":                                    {},
	"cmd/objdump":                               {},
	"cmd/pack":                                  {},
	"cmd/pprof":                                 {},
	"cmd/test2json":                             {},
	"cmd/trace":                                 {},
	"cmd/vendor/github.com/google/pprof/driver": {},
	"cmd/vendor/github.com/google/pprof/internal/binutils":        {},
	"cmd/vendor/github.com/google/pprof/internal/driver":          {},
	"cmd/vendor/github.com/google/pprof/internal/elfexec":         {},
	"cmd/vendor/github.com/google/pprof/internal/graph":           {},
	"cmd/vendor/github.com/google/pprof/internal/measurement":     {},
	"cmd/vendor/github.com/google/pprof/internal/plugin":          {},
	"cmd/vendor/github.com/google/pprof/internal/proftest":        {},
	"cmd/vendor/github.com/google/pprof/internal/report":          {},
	"cmd/vendor/github.com/google/pprof/internal/symbolizer":      {},
	"cmd/vendor/github.com/google/pprof/internal/symbolz":         {},
	"cmd/vendor/github.com/google/pprof/profile":                  {},
	"cmd/vendor/github.com/google/pprof/third_party/d3":           {},
	"cmd/vendor/github.com/google/pprof/third_party/d3flamegraph": {},
	"cmd/vendor/github.com/google/pprof/third_party/svgpan":       {},
	"cmd/vendor/github.com/ianlancetaylor/demangle":               {},
	"cmd/vendor/golang.org/x/arch/arm/armasm":                     {},
	"cmd/vendor/golang.org/x/arch/arm64/arm64asm":                 {},
	"cmd/vendor/golang.org/x/arch/ppc64/ppc64asm":                 {},
	"cmd/vendor/golang.org/x/arch/x86/x86asm":                     {},
	"cmd/vendor/golang.org/x/crypto/ssh/terminal":                 {},
	"cmd/vendor/golang.org/x/sys/unix":                            {},
	"cmd/vendor/golang.org/x/sys/windows":                         {},
	"cmd/vendor/golang.org/x/sys/windows/registry":                {},
	"cmd/vendor/golang.org/x/sys/windows/svc":                     {},
	"cmd/vendor/golang.org/x/sys/windows/svc/debug":               {},
	"cmd/vendor/golang.org/x/sys/windows/svc/eventlog":            {},
	"cmd/vendor/golang.org/x/sys/windows/svc/mgr":                 {},
	"cmd/vet":                           {},
	"cmd/vet/internal/cfg":              {},
	"cmd/vet/internal/whitelist":        {},
	"compress/bzip2":                    {},
	"compress/flate":                    {},
	"compress/gzip":                     {},
	"compress/lzw":                      {},
	"compress/zlib":                     {},
	"container/heap":                    {},
	"container/list":                    {},
	"container/ring":                    {},
	"context":                           {},
	"crypto":                            {},
	"crypto/aes":                        {},
	"crypto/cipher":                     {},
	"crypto/des":                        {},
	"crypto/dsa":                        {},
	"crypto/ecdsa":                      {},
	"crypto/elliptic":                   {},
	"crypto/hmac":                       {},
	"crypto/internal/randutil":          {},
	"crypto/internal/subtle":            {},
	"crypto/md5":                        {},
	"crypto/rand":                       {},
	"crypto/rc4":                        {},
	"crypto/rsa":                        {},
	"crypto/sha1":                       {},
	"crypto/sha256":                     {},
	"crypto/sha512":                     {},
	"crypto/subtle":                     {},
	"crypto/tls":                        {},
	"crypto/x509":                       {},
	"crypto/x509/pkix":                  {},
	"database/sql":                      {},
	"database/sql/driver":               {},
	"debug/dwarf":                       {},
	"debug/elf":                         {},
	"debug/gosym":                       {},
	"debug/macho":                       {},
	"debug/pe":                          {},
	"debug/plan9obj":                    {},
	"encoding":                          {},
	"encoding/ascii85":                  {},
	"encoding/asn1":                     {},
	"encoding/base32":                   {},
	"encoding/base64":                   {},
	"encoding/binary":                   {},
	"encoding/csv":                      {},
	"encoding/gob":                      {},
	"encoding/hex":                      {},
	"encoding/json":                     {},
	"encoding/pem":                      {},
	"encoding/xml":                      {},
	"errors":                            {},
	"expvar":                            {},
	"flag":                              {},
	"fmt":                               {},
	"go/ast":                            {},
	"go/build":                          {},
	"go/constant":                       {},
	"go/doc":                            {},
	"go/format":                         {},
	"go/importer":                       {},
	"go/internal/gccgoimporter":         {},
	"go/internal/gcimporter":            {},
	"go/internal/srcimporter":           {},
	"go/parser":                         {},
	"go/printer":                        {},
	"go/scanner":                        {},
	"go/token":                          {},
	"go/types":                          {},
	"hash":                              {},
	"hash/adler32":                      {},
	"hash/crc32":                        {},
	"hash/crc64":                        {},
	"hash/fnv":                          {},
	"html":                              {},
	"html/template":                     {},
	"image":                             {},
	"image/color":                       {},
	"image/color/palette":               {},
	"image/draw":                        {},
	"image/gif":                         {},
	"image/internal/imageutil":          {},
	"image/jpeg":                        {},
	"image/png":                         {},
	"index/suffixarray":                 {},
	"internal/bytealg":                  {},
	"internal/cpu":                      {},
	"internal/nettrace":                 {},
	"internal/poll":                     {},
	"internal/race":                     {},
	"internal/singleflight":             {},
	"internal/syscall/unix":             {},
	"internal/syscall/windows":          {},
	"internal/syscall/windows/registry": {},
	"internal/syscall/windows/sysdll":   {},
	"internal/testenv":                  {},
	"internal/testlog":                  {},
	"internal/trace":                    {},
	"io":                                {},
	"io/ioutil":                         {},
	"log":                               {},
	"log/syslog":                        {},
	"math":                              {},
	"math/big":                          {},
	"math/bits":                         {},
	"math/cmplx":                        {},
	"math/rand":                         {},
	"mime":                              {},
	"mime/multipart":                    {},
	"mime/quotedprintable":              {},
	"net":                               {},
	"net/http":                          {},
	"net/http/cgi":                      {},
	"net/http/cookiejar":                {},
	"net/http/fcgi":                     {},
	"net/http/httptest":                 {},
	"net/http/httptrace":                {},
	"net/http/httputil":                 {},
	"net/http/internal":                 {},
	"net/http/pprof":                    {},
	"net/internal/socktest":             {},
	"net/mail":                          {},
	"net/rpc":                           {},
	"net/rpc/jsonrpc":                   {},
	"net/smtp":                          {},
	"net/textproto":                     {},
	"net/url":                           {},
	"os":                                {},
	"os/exec":                           {},
	"os/signal":                         {},
	"os/signal/internal/pty":            {},
	"os/user":                           {},
	"path":                              {},
	"path/filepath":                     {},
	"plugin":                            {},
	"reflect":                           {},
	"regexp":                            {},
	"regexp/syntax":                     {},
	"runtime":                           {},
	"runtime/cgo":                       {},
	"runtime/debug":                     {},
	"runtime/internal/atomic":           {},
	"runtime/internal/sys":              {},
	"runtime/pprof":                     {},
	"runtime/pprof/internal/profile":    {},
	"runtime/race":                      {},
	"runtime/trace":                     {},
	"sort":                              {},
	"strconv":                           {},
	"strings":                           {},
	"sync":                              {},
	"sync/atomic":                       {},
	"syscall":                           {},
	"testing":                           {},
	"testing/internal/testdeps":         {},
	"testing/iotest":                    {},
	"testing/quick":                     {},
	"text/scanner":                      {},
	"text/tabwriter":                    {},
	"text/template":                     {},
	"text/template/parse":               {},
	"time":                              {},
	"unicode":                           {},
	"unicode/utf16":                     {},
	"unicode/utf8":                      {},
	"unsafe":                            {},
	"vendor/golang_org/x/crypto/chacha20poly1305":  {},
	"vendor/golang_org/x/crypto/cryptobyte":        {},
	"vendor/golang_org/x/crypto/cryptobyte/asn1":   {},
	"vendor/golang_org/x/crypto/curve25519":        {},
	"vendor/golang_org/x/crypto/internal/chacha20": {},
	"vendor/golang_org/x/crypto/poly1305":          {},
	"vendor/golang_org/x/net/dns/dnsmessage":       {},
	"vendor/golang_org/x/net/http/httpguts":        {},
	"vendor/golang_org/x/net/http/httpproxy":       {},
	"vendor/golang_org/x/net/http2/hpack":          {},
	"vendor/golang_org/x/net/idna":                 {},
	"vendor/golang_org/x/net/internal/nettest":     {},
	"vendor/golang_org/x/net/nettest":              {},
	"vendor/golang_org/x/net/route":                {},
	"vendor/golang_org/x/text/secure":              {},
	"vendor/golang_org/x/text/secure/bidirule":     {},
	"vendor/golang_org/x/text/transform":           {},
	"vendor/golang_org/x/text/unicode":             {},
	"vendor/golang_org/x/text/unicode/bidi":        {},
	"vendor/golang_org/x/text/unicode/norm":        {},
// existingDirectories is a set of import paths of Go directories that are known to exist.
// It includes directories in Go standard library and sub-repositories.
var existingDirectories map[string]struct{}

func initExistingDirectories() error {
	existingDirectories = make(map[string]struct{})
	for servProj, repoRoot := range gerritProjects {
		for _, branch := range []string{"master", "release-branch.go1.12", "release-branch.go1.11"} {
			dirs, err := walkRepositoryBranch("https://"+servProj, repoRoot, branch)
			if err == errBranchNotFound && branch != "master" {
				// Skip missing release branch.
				continue
			} else if err != nil {
				return fmt.Errorf("walkRepositoryBranch(%q, %q, %q): %v", "https://"+servProj, repoRoot, branch, err)
			}
			for d := range dirs {
				existingDirectories[d] = struct{}{}
			}
		}
	}
	return nil
}

func walkRepositoryBranch(repoURL, repoRoot, branch string) (map[string]struct{}, error) {
	r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
		URL:           repoURL,
		ReferenceName: plumbing.NewBranchReferenceName(branch),
		SingleBranch:  true,
		Depth:         1,
		Tags:          git.NoTags,
	})
	if err != nil && err.Error() == fmt.Sprintf("couldn't find remote ref %q", plumbing.NewBranchReferenceName(branch)) {
		return nil, errBranchNotFound
	} else if err != nil {
		return nil, err
	}
	head, err := r.Head()
	if err != nil {
		return nil, err
	}
	commit, err := r.CommitObject(head.Hash())
	if err != nil {
		return nil, err
	}
	tree, err := r.TreeObject(commit.TreeHash)
	if err != nil {
		return nil, err
	}
	if repoRoot == "" {
		// Walk "/src" subdirectory of main Go repository.
		tree, err = subTree(r, tree, "src")
		if err != nil {
			return nil, err
		}
	}
	var dirs = make(map[string]struct{})
	type treePath struct {
		*object.Tree
		Path string
	}
	for frontier := []treePath{{Tree: tree}}; len(frontier) > 0; frontier = frontier[1:] {
		t := frontier[0]

		// Enqueue subdirectories.
		for _, e := range t.Entries {
			if e.Mode != filemode.Dir {
				// We only care about directories.
				continue
			}
			if strings.HasPrefix(e.Name, ".") || strings.HasPrefix(e.Name, "_") || e.Name == "testdata" {
				continue
			}

			tree, err := r.TreeObject(e.Hash)
			if err != nil {
				return nil, err
			}
			frontier = append(frontier, treePath{
				Tree: tree,
				Path: path.Join(t.Path, e.Name),
			})
		}

		// Process this directory.
		if repoRoot == "" && t.Path == "" {
			// Skip root of "/src" of main Go repository.
			continue
		}
		dirs[path.Join(repoRoot, t.Path)] = struct{}{}
	}
	return dirs, nil
}

var errBranchNotFound = errors.New("branch not found")

	"golang.org/x/arch/arm/armasm":                                    {},
	"golang.org/x/arch/arm/armmap":                                    {},
	"golang.org/x/arch/arm/armspec":                                   {},
	"golang.org/x/arch/arm64/arm64asm":                                {},
	"golang.org/x/arch/arm64/arm64spec":                               {},
	"golang.org/x/arch/ppc64/ppc64asm":                                {},
	"golang.org/x/arch/ppc64/ppc64map":                                {},
	"golang.org/x/arch/ppc64/ppc64spec":                               {},
	"golang.org/x/arch/x86/x86asm":                                    {},
	"golang.org/x/arch/x86/x86avxgen":                                 {},
	"golang.org/x/arch/x86/x86csv":                                    {},
	"golang.org/x/arch/x86/x86map":                                    {},
	"golang.org/x/arch/x86/x86spec":                                   {},
	"golang.org/x/arch/x86/xeddata":                                   {},
	"golang.org/x/benchmarks/build":                                   {},
	"golang.org/x/benchmarks/driver":                                  {},
	"golang.org/x/benchmarks/garbage":                                 {},
	"golang.org/x/benchmarks/http":                                    {},
	"golang.org/x/benchmarks/json":                                    {},
	"golang.org/x/blog":                                               {},
	"golang.org/x/blog/content/appengine":                             {},
	"golang.org/x/blog/content/cover":                                 {},
	"golang.org/x/blog/content/h2push/server":                         {},
	"golang.org/x/blog/content/survey2016":                            {},
	"golang.org/x/blog/content/survey2017":                            {},
	"golang.org/x/blog/support/racy":                                  {},
	"golang.org/x/build":                                              {},
	"golang.org/x/build/autocertcache":                                {},
	"golang.org/x/build/buildenv":                                     {},
	"golang.org/x/build/buildlet":                                     {},
	"golang.org/x/build/cmd/builder":                                  {},
	"golang.org/x/build/cmd/buildlet":                                 {},
	"golang.org/x/build/cmd/buildlet/stage0":                          {},
	"golang.org/x/build/cmd/buildstats":                               {},
	"golang.org/x/build/cmd/buzzkill":                                 {},
	"golang.org/x/build/cmd/cl":                                       {},
	"golang.org/x/build/cmd/coordinator":                              {},
	"golang.org/x/build/cmd/coordinator/buildongce":                   {},
	"golang.org/x/build/cmd/coordinator/metrics":                      {},
	"golang.org/x/build/cmd/coordinator/spanlog":                      {},
	"golang.org/x/build/cmd/debugnewvm":                               {},
	"golang.org/x/build/cmd/docker2boot":                              {},
	"golang.org/x/build/cmd/fetchlogs":                                {},
	"golang.org/x/build/cmd/genbootstrap":                             {},
	"golang.org/x/build/cmd/gerritbot":                                {},
	"golang.org/x/build/cmd/gitlock":                                  {},
	"golang.org/x/build/cmd/gitmirror":                                {},
	"golang.org/x/build/cmd/gomote":                                   {},
	"golang.org/x/build/cmd/gopherbot":                                {},
	"golang.org/x/build/cmd/gopherstats":                              {},
	"golang.org/x/build/cmd/makemac":                                  {},
	"golang.org/x/build/cmd/perfrun":                                  {},
	"golang.org/x/build/cmd/pubsubhelper":                             {},
	"golang.org/x/build/cmd/pubsubhelper/pubsubtypes":                 {},
	"golang.org/x/build/cmd/racebuild":                                {},
	"golang.org/x/build/cmd/release":                                  {},
	"golang.org/x/build/cmd/releasebot":                               {},
	"golang.org/x/build/cmd/relnote":                                  {},
	"golang.org/x/build/cmd/retrybuilds":                              {},
	"golang.org/x/build/cmd/rundockerbuildlet":                        {},
	"golang.org/x/build/cmd/scaleway":                                 {},
	"golang.org/x/build/cmd/upload":                                   {},
	"golang.org/x/build/cmd/xb":                                       {},
	"golang.org/x/build/dashboard":                                    {},
	"golang.org/x/build/devapp":                                       {},
	"golang.org/x/build/devapp/owners":                                {},
	"golang.org/x/build/envutil":                                      {},
	"golang.org/x/build/gerrit":                                       {},
	"golang.org/x/build/internal/buildgo":                             {},
	"golang.org/x/build/internal/buildstats":                          {},
	"golang.org/x/build/internal/gitauth":                             {},
	"golang.org/x/build/internal/gophers":                             {},
	"golang.org/x/build/internal/httpdl":                              {},
	"golang.org/x/build/internal/https":                               {},
	"golang.org/x/build/internal/loghash":                             {},
	"golang.org/x/build/internal/lru":                                 {},
	"golang.org/x/build/internal/singleflight":                        {},
	"golang.org/x/build/internal/sourcecache":                         {},
	"golang.org/x/build/internal/untar":                               {},
	"golang.org/x/build/kubernetes":                                   {},
	"golang.org/x/build/kubernetes/api":                               {},
	"golang.org/x/build/kubernetes/gke":                               {},
	"golang.org/x/build/livelog":                                      {},
	"golang.org/x/build/maintner":                                     {},
	"golang.org/x/build/maintner/cmd/maintserve":                      {},
	"golang.org/x/build/maintner/godata":                              {},
	"golang.org/x/build/maintner/gostats":                             {},
	"golang.org/x/build/maintner/maintnerd":                           {},
	"golang.org/x/build/maintner/maintnerd/apipb":                     {},
	"golang.org/x/build/maintner/maintnerd/gcslog":                    {},
	"golang.org/x/build/maintner/maintnerd/maintapi":                  {},
	"golang.org/x/build/maintner/maintpb":                             {},
	"golang.org/x/build/maintner/maintq":                              {},
	"golang.org/x/build/maintner/reclog":                              {},
	"golang.org/x/build/pargzip":                                      {},
	"golang.org/x/build/revdial":                                      {},
	"golang.org/x/build/status":                                       {},
	"golang.org/x/build/status/statusserver":                          {},
	"golang.org/x/build/tarutil":                                      {},
	"golang.org/x/build/types":                                        {},
	"golang.org/x/build/vcs-test/vcweb":                               {},
	"golang.org/x/build/version":                                      {},
	"golang.org/x/build/version/go1.10":                               {},
	"golang.org/x/build/version/go1.10.1":                             {},
	"golang.org/x/build/version/go1.10.2":                             {},
	"golang.org/x/build/version/go1.10.3":                             {},
	"golang.org/x/build/version/go1.10beta1":                          {},
	"golang.org/x/build/version/go1.10beta2":                          {},
	"golang.org/x/build/version/go1.10rc1":                            {},
	"golang.org/x/build/version/go1.10rc2":                            {},
	"golang.org/x/build/version/go1.11beta1":                          {},
	"golang.org/x/build/version/go1.8":                                {},
	"golang.org/x/build/version/go1.8.1":                              {},
	"golang.org/x/build/version/go1.8.2":                              {},
	"golang.org/x/build/version/go1.8.3":                              {},
	"golang.org/x/build/version/go1.8.4":                              {},
	"golang.org/x/build/version/go1.8.5":                              {},
	"golang.org/x/build/version/go1.8.6":                              {},
	"golang.org/x/build/version/go1.8.7":                              {},
	"golang.org/x/build/version/go1.8beta1":                           {},
	"golang.org/x/build/version/go1.8beta2":                           {},
	"golang.org/x/build/version/go1.8rc1":                             {},
	"golang.org/x/build/version/go1.8rc2":                             {},
	"golang.org/x/build/version/go1.8rc3":                             {},
	"golang.org/x/build/version/go1.9":                                {},
	"golang.org/x/build/version/go1.9.1":                              {},
	"golang.org/x/build/version/go1.9.2":                              {},
	"golang.org/x/build/version/go1.9.3":                              {},
	"golang.org/x/build/version/go1.9.4":                              {},
	"golang.org/x/build/version/go1.9.5":                              {},
	"golang.org/x/build/version/go1.9.6":                              {},
	"golang.org/x/build/version/go1.9.7":                              {},
	"golang.org/x/build/version/go1.9beta1":                           {},
	"golang.org/x/build/version/go1.9beta2":                           {},
	"golang.org/x/build/version/go1.9rc1":                             {},
	"golang.org/x/build/version/go1.9rc2":                             {},
	"golang.org/x/crypto/acme":                                        {},
	"golang.org/x/crypto/acme/autocert":                               {},
	"golang.org/x/crypto/acme/autocert/internal/acmetest":             {},
	"golang.org/x/crypto/argon2":                                      {},
	"golang.org/x/crypto/bcrypt":                                      {},
	"golang.org/x/crypto/blake2b":                                     {},
	"golang.org/x/crypto/blake2s":                                     {},
	"golang.org/x/crypto/blowfish":                                    {},
	"golang.org/x/crypto/bn256":                                       {},
	"golang.org/x/crypto/cast5":                                       {},
	"golang.org/x/crypto/chacha20poly1305":                            {},
	"golang.org/x/crypto/cryptobyte":                                  {},
	"golang.org/x/crypto/cryptobyte/asn1":                             {},
	"golang.org/x/crypto/curve25519":                                  {},
	"golang.org/x/crypto/ed25519":                                     {},
	"golang.org/x/crypto/ed25519/internal/edwards25519":               {},
	"golang.org/x/crypto/hkdf":                                        {},
	"golang.org/x/crypto/internal/chacha20":                           {},
	"golang.org/x/crypto/internal/subtle":                             {},
	"golang.org/x/crypto/md4":                                         {},
	"golang.org/x/crypto/nacl/auth":                                   {},
	"golang.org/x/crypto/nacl/box":                                    {},
	"golang.org/x/crypto/nacl/secretbox":                              {},
	"golang.org/x/crypto/nacl/sign":                                   {},
	"golang.org/x/crypto/ocsp":                                        {},
	"golang.org/x/crypto/openpgp":                                     {},
	"golang.org/x/crypto/openpgp/armor":                               {},
	"golang.org/x/crypto/openpgp/clearsign":                           {},
	"golang.org/x/crypto/openpgp/elgamal":                             {},
	"golang.org/x/crypto/openpgp/errors":                              {},
	"golang.org/x/crypto/openpgp/packet":                              {},
	"golang.org/x/crypto/openpgp/s2k":                                 {},
	"golang.org/x/crypto/otr":                                         {},
	"golang.org/x/crypto/pbkdf2":                                      {},
	"golang.org/x/crypto/pkcs12":                                      {},
	"golang.org/x/crypto/pkcs12/internal/rc2":                         {},
	"golang.org/x/crypto/poly1305":                                    {},
	"golang.org/x/crypto/ripemd160":                                   {},
	"golang.org/x/crypto/salsa20":                                     {},
	"golang.org/x/crypto/salsa20/salsa":                               {},
	"golang.org/x/crypto/scrypt":                                      {},
	"golang.org/x/crypto/sha3":                                        {},
	"golang.org/x/crypto/ssh":                                         {},
	"golang.org/x/crypto/ssh/agent":                                   {},
	"golang.org/x/crypto/ssh/knownhosts":                              {},
	"golang.org/x/crypto/ssh/terminal":                                {},
	"golang.org/x/crypto/ssh/test":                                    {},
	"golang.org/x/crypto/tea":                                         {},
	"golang.org/x/crypto/twofish":                                     {},
	"golang.org/x/crypto/xtea":                                        {},
	"golang.org/x/crypto/xts":                                         {},
	"golang.org/x/debug/cmd/viewcore":                                 {},
	"golang.org/x/debug/internal/core":                                {},
	"golang.org/x/debug/internal/gocore":                              {},
	"golang.org/x/exp/cmd/macos-roots-test":                           {},
	"golang.org/x/exp/ebnf":                                           {},
	"golang.org/x/exp/ebnflint":                                       {},
	"golang.org/x/exp/errors":                                         {},
	"golang.org/x/exp/errors/fmt":                                     {},
	"golang.org/x/exp/io/i2c":                                         {},
	"golang.org/x/exp/io/i2c/driver":                                  {},
	"golang.org/x/exp/io/i2c/example/displayip":                       {},
	"golang.org/x/exp/io/spi":                                         {},
	"golang.org/x/exp/io/spi/driver":                                  {},
	"golang.org/x/exp/mmap":                                           {},
	"golang.org/x/exp/old/netchan":                                    {},
	"golang.org/x/exp/rand":                                           {},
	"golang.org/x/exp/shiny/driver":                                   {},
	"golang.org/x/exp/shiny/driver/gldriver":                          {},
	"golang.org/x/exp/shiny/driver/internal/drawer":                   {},
	"golang.org/x/exp/shiny/driver/internal/errscreen":                {},
	"golang.org/x/exp/shiny/driver/internal/event":                    {},
	"golang.org/x/exp/shiny/driver/internal/lifecycler":               {},
	"golang.org/x/exp/shiny/driver/internal/swizzle":                  {},
	"golang.org/x/exp/shiny/driver/internal/win32":                    {},
	"golang.org/x/exp/shiny/driver/internal/x11key":                   {},
	"golang.org/x/exp/shiny/driver/windriver":                         {},
	"golang.org/x/exp/shiny/driver/x11driver":                         {},
	"golang.org/x/exp/shiny/gesture":                                  {},
	"golang.org/x/exp/shiny/iconvg":                                   {},
	"golang.org/x/exp/shiny/iconvg/internal/gradient":                 {},
	"golang.org/x/exp/shiny/imageutil":                                {},
	"golang.org/x/exp/shiny/materialdesign/colornames":                {},
	"golang.org/x/exp/shiny/materialdesign/icons":                     {},
	"golang.org/x/exp/shiny/screen":                                   {},
	"golang.org/x/exp/shiny/text":                                     {},
	"golang.org/x/exp/shiny/unit":                                     {},
	"golang.org/x/exp/shiny/widget":                                   {},
	"golang.org/x/exp/shiny/widget/flex":                              {},
	"golang.org/x/exp/shiny/widget/glwidget":                          {},
	"golang.org/x/exp/shiny/widget/node":                              {},
	"golang.org/x/exp/shiny/widget/theme":                             {},
	"golang.org/x/exp/utf8string":                                     {},
	"golang.org/x/exp/winfsnotify":                                    {},
	"golang.org/x/image/bmp":                                          {},
	"golang.org/x/image/colornames":                                   {},
	"golang.org/x/image/draw":                                         {},
	"golang.org/x/image/font":                                         {},
	"golang.org/x/image/font/basicfont":                               {},
	"golang.org/x/image/font/gofont/gobold":                           {},
	"golang.org/x/image/font/gofont/gobolditalic":                     {},
	"golang.org/x/image/font/gofont/goitalic":                         {},
	"golang.org/x/image/font/gofont/gomedium":                         {},
	"golang.org/x/image/font/gofont/gomediumitalic":                   {},
	"golang.org/x/image/font/gofont/gomono":                           {},
	"golang.org/x/image/font/gofont/gomonobold":                       {},
	"golang.org/x/image/font/gofont/gomonobolditalic":                 {},
	"golang.org/x/image/font/gofont/gomonoitalic":                     {},
	"golang.org/x/image/font/gofont/goregular":                        {},
	"golang.org/x/image/font/gofont/gosmallcaps":                      {},
	"golang.org/x/image/font/gofont/gosmallcapsitalic":                {},
	"golang.org/x/image/font/inconsolata":                             {},
	"golang.org/x/image/font/opentype":                                {},
	"golang.org/x/image/font/plan9font":                               {},
	"golang.org/x/image/font/sfnt":                                    {},
	"golang.org/x/image/math/f32":                                     {},
	"golang.org/x/image/math/f64":                                     {},
	"golang.org/x/image/math/fixed":                                   {},
	"golang.org/x/image/riff":                                         {},
	"golang.org/x/image/tiff":                                         {},
	"golang.org/x/image/tiff/lzw":                                     {},
	"golang.org/x/image/vector":                                       {},
	"golang.org/x/image/vp8":                                          {},
	"golang.org/x/image/vp8l":                                         {},
	"golang.org/x/image/webp":                                         {},
	"golang.org/x/image/webp/nycbcra":                                 {},
	"golang.org/x/lint":                                               {},
	"golang.org/x/lint/golint":                                        {},
	"golang.org/x/mobile/app":                                         {},
	"golang.org/x/mobile/app/internal/apptest":                        {},
	"golang.org/x/mobile/app/internal/testapp":                        {},
	"golang.org/x/mobile/asset":                                       {},
	"golang.org/x/mobile/bind":                                        {},
	"golang.org/x/mobile/bind/java":                                   {},
	"golang.org/x/mobile/bind/objc":                                   {},
	"golang.org/x/mobile/bind/seq":                                    {},
	"golang.org/x/mobile/cmd/gobind":                                  {},
	"golang.org/x/mobile/cmd/gomobile":                                {},
	"golang.org/x/mobile/event/key":                                   {},
	"golang.org/x/mobile/event/lifecycle":                             {},
	"golang.org/x/mobile/event/mouse":                                 {},
	"golang.org/x/mobile/event/paint":                                 {},
	"golang.org/x/mobile/event/size":                                  {},
	"golang.org/x/mobile/event/touch":                                 {},
	"golang.org/x/mobile/example/basic":                               {},
	"golang.org/x/mobile/example/bind/hello":                          {},
	"golang.org/x/mobile/example/flappy":                              {},
	"golang.org/x/mobile/example/network":                             {},
	"golang.org/x/mobile/exp/app/debug":                               {},
	"golang.org/x/mobile/exp/audio/al":                                {},
	"golang.org/x/mobile/exp/f32":                                     {},
	"golang.org/x/mobile/exp/font":                                    {},
	"golang.org/x/mobile/exp/gl/glutil":                               {},
	"golang.org/x/mobile/exp/sensor":                                  {},
	"golang.org/x/mobile/exp/sprite":                                  {},
	"golang.org/x/mobile/exp/sprite/clock":                            {},
	"golang.org/x/mobile/exp/sprite/glsprite":                         {},
	"golang.org/x/mobile/exp/sprite/portable":                         {},
	"golang.org/x/mobile/geom":                                        {},
	"golang.org/x/mobile/gl":                                          {},
	"golang.org/x/mobile/internal/binres":                             {},
	"golang.org/x/mobile/internal/importers":                          {},
	"golang.org/x/mobile/internal/importers/java":                     {},
	"golang.org/x/mobile/internal/importers/objc":                     {},
	"golang.org/x/mobile/internal/mobileinit":                         {},
	"golang.org/x/net/bpf":                                            {},
	"golang.org/x/net/context":                                        {},
	"golang.org/x/net/context/ctxhttp":                                {},
	"golang.org/x/net/dict":                                           {},
	"golang.org/x/net/dns/dnsmessage":                                 {},
	"golang.org/x/net/html":                                           {},
	"golang.org/x/net/html/atom":                                      {},
	"golang.org/x/net/html/charset":                                   {},
	"golang.org/x/net/http/httpguts":                                  {},
	"golang.org/x/net/http/httpproxy":                                 {},
	"golang.org/x/net/http2":                                          {},
	"golang.org/x/net/http2/h2c":                                      {},
	"golang.org/x/net/http2/h2i":                                      {},
	"golang.org/x/net/http2/hpack":                                    {},
	"golang.org/x/net/icmp":                                           {},
	"golang.org/x/net/idna":                                           {},
	"golang.org/x/net/internal/iana":                                  {},
	"golang.org/x/net/internal/nettest":                               {},
	"golang.org/x/net/internal/socket":                                {},
	"golang.org/x/net/internal/socks":                                 {},
	"golang.org/x/net/internal/sockstest":                             {},
	"golang.org/x/net/internal/timeseries":                            {},
	"golang.org/x/net/ipv4":                                           {},
	"golang.org/x/net/ipv6":                                           {},
	"golang.org/x/net/nettest":                                        {},
	"golang.org/x/net/netutil":                                        {},
	"golang.org/x/net/proxy":                                          {},
	"golang.org/x/net/publicsuffix":                                   {},
	"golang.org/x/net/route":                                          {},
	"golang.org/x/net/trace":                                          {},
	"golang.org/x/net/webdav":                                         {},
	"golang.org/x/net/webdav/internal/xml":                            {},
	"golang.org/x/net/websocket":                                      {},
	"golang.org/x/net/xsrftoken":                                      {},
	"golang.org/x/oauth2":                                             {},
	"golang.org/x/oauth2/amazon":                                      {},
	"golang.org/x/oauth2/bitbucket":                                   {},
	"golang.org/x/oauth2/cern":                                        {},
	"golang.org/x/oauth2/clientcredentials":                           {},
	"golang.org/x/oauth2/facebook":                                    {},
	"golang.org/x/oauth2/fitbit":                                      {},
	"golang.org/x/oauth2/foursquare":                                  {},
	"golang.org/x/oauth2/github":                                      {},
	"golang.org/x/oauth2/gitlab":                                      {},
	"golang.org/x/oauth2/google":                                      {},
	"golang.org/x/oauth2/heroku":                                      {},
	"golang.org/x/oauth2/hipchat":                                     {},
	"golang.org/x/oauth2/instagram":                                   {},
	"golang.org/x/oauth2/internal":                                    {},
	"golang.org/x/oauth2/jira":                                        {},
	"golang.org/x/oauth2/jws":                                         {},
	"golang.org/x/oauth2/jwt":                                         {},
	"golang.org/x/oauth2/kakao":                                       {},
	"golang.org/x/oauth2/linkedin":                                    {},
	"golang.org/x/oauth2/mailchimp":                                   {},
	"golang.org/x/oauth2/mailru":                                      {},
	"golang.org/x/oauth2/mediamath":                                   {},
	"golang.org/x/oauth2/microsoft":                                   {},
	"golang.org/x/oauth2/nokiahealth":                                 {},
	"golang.org/x/oauth2/odnoklassniki":                               {},
	"golang.org/x/oauth2/paypal":                                      {},
	"golang.org/x/oauth2/slack":                                       {},
	"golang.org/x/oauth2/spotify":                                     {},
	"golang.org/x/oauth2/stackoverflow":                               {},
	"golang.org/x/oauth2/twitch":                                      {},
	"golang.org/x/oauth2/uber":                                        {},
	"golang.org/x/oauth2/vk":                                          {},
	"golang.org/x/oauth2/yahoo":                                       {},
	"golang.org/x/oauth2/yandex":                                      {},
	"golang.org/x/perf/analysis/app":                                  {},
	"golang.org/x/perf/analysis/localperf":                            {},
	"golang.org/x/perf/benchstat":                                     {},
	"golang.org/x/perf/cmd/benchsave":                                 {},
	"golang.org/x/perf/cmd/benchstat":                                 {},
	"golang.org/x/perf/internal/basedir":                              {},
	"golang.org/x/perf/internal/diff":                                 {},
	"golang.org/x/perf/internal/stats":                                {},
	"golang.org/x/perf/storage":                                       {},
	"golang.org/x/perf/storage/app":                                   {},
	"golang.org/x/perf/storage/benchfmt":                              {},
	"golang.org/x/perf/storage/db":                                    {},
	"golang.org/x/perf/storage/db/dbtest":                             {},
	"golang.org/x/perf/storage/db/sqlite3":                            {},
	"golang.org/x/perf/storage/fs":                                    {},
	"golang.org/x/perf/storage/fs/gcs":                                {},
	"golang.org/x/perf/storage/fs/local":                              {},
	"golang.org/x/perf/storage/localperfdata":                         {},
	"golang.org/x/perf/storage/query":                                 {},
	"golang.org/x/playground":                                         {},
	"golang.org/x/review/git-codereview":                              {},
	"golang.org/x/sync/errgroup":                                      {},
	"golang.org/x/sync/semaphore":                                     {},
	"golang.org/x/sync/singleflight":                                  {},
	"golang.org/x/sync/syncmap":                                       {},
	"golang.org/x/sys/cpu":                                            {},
	"golang.org/x/sys/unix":                                           {},
	"golang.org/x/sys/windows":                                        {},
	"golang.org/x/sys/windows/registry":                               {},
	"golang.org/x/sys/windows/svc":                                    {},
	"golang.org/x/sys/windows/svc/debug":                              {},
	"golang.org/x/sys/windows/svc/eventlog":                           {},
	"golang.org/x/sys/windows/svc/example":                            {},
	"golang.org/x/sys/windows/svc/mgr":                                {},
	"golang.org/x/talks/content/2014/go4java/runner":                  {},
	"golang.org/x/talks/content/2014/organizeio":                      {},
	"golang.org/x/talks/content/2014/research2":                       {},
	"golang.org/x/talks/content/2014/static-analysis/egtest":          {},
	"golang.org/x/talks/content/2014/taste":                           {},
	"golang.org/x/talks/content/2014/testing/subprocess":              {},
	"golang.org/x/talks/content/2014/testing/test1":                   {},
	"golang.org/x/talks/content/2014/testing/test2":                   {},
	"golang.org/x/talks/content/2015/keeping-up":                      {},
	"golang.org/x/talks/content/2015/tricks/broadcastwriter":          {},
	"golang.org/x/talks/content/2015/tricks/subprocess":               {},
	"golang.org/x/talks/content/2016/applicative/google":              {},
	"golang.org/x/talks/content/2016/asm":                             {},
	"golang.org/x/talks/content/2017/state-of-go-may/alias":           {},
	"golang.org/x/talks/content/2017/state-of-go-may/bits":            {},
	"golang.org/x/talks/content/2017/state-of-go-may/exec":            {},
	"golang.org/x/talks/content/2017/state-of-go-may/exec/getenv":     {},
	"golang.org/x/talks/content/2017/state-of-go-may/html":            {},
	"golang.org/x/talks/content/2017/state-of-go-may/syncmap":         {},
	"golang.org/x/talks/content/2017/state-of-go/stdlib/sort":         {},
	"golang.org/x/term":                                               {},
	"golang.org/x/text":                                               {},
	"golang.org/x/text/cases":                                         {},
	"golang.org/x/text/cmd/gotext":                                    {},
	"golang.org/x/text/cmd/gotext/examples/extract":                   {},
	"golang.org/x/text/cmd/gotext/examples/extract_http":              {},
	"golang.org/x/text/cmd/gotext/examples/extract_http/pkg":          {},
	"golang.org/x/text/cmd/gotext/examples/rewrite":                   {},
	"golang.org/x/text/collate":                                       {},
	"golang.org/x/text/collate/build":                                 {},
	"golang.org/x/text/collate/tools/colcmp":                          {},
	"golang.org/x/text/currency":                                      {},
	"golang.org/x/text/date":                                          {},
	"golang.org/x/text/encoding":                                      {},
	"golang.org/x/text/encoding/charmap":                              {},
	"golang.org/x/text/encoding/htmlindex":                            {},
	"golang.org/x/text/encoding/ianaindex":                            {},
	"golang.org/x/text/encoding/internal":                             {},
	"golang.org/x/text/encoding/internal/enctest":                     {},
	"golang.org/x/text/encoding/internal/identifier":                  {},
	"golang.org/x/text/encoding/japanese":                             {},
	"golang.org/x/text/encoding/korean":                               {},
	"golang.org/x/text/encoding/simplifiedchinese":                    {},
	"golang.org/x/text/encoding/traditionalchinese":                   {},
	"golang.org/x/text/encoding/unicode":                              {},
	"golang.org/x/text/encoding/unicode/utf32":                        {},
	"golang.org/x/text/feature/plural":                                {},
	"golang.org/x/text/internal":                                      {},
	"golang.org/x/text/internal/catmsg":                               {},
	"golang.org/x/text/internal/cldrtree":                             {},
	"golang.org/x/text/internal/colltab":                              {},
	"golang.org/x/text/internal/export/idna":                          {},
	"golang.org/x/text/internal/format":                               {},
	"golang.org/x/text/internal/gen":                                  {},
	"golang.org/x/text/internal/gen/bitfield":                         {},
	"golang.org/x/text/internal/language":                             {},
	"golang.org/x/text/internal/language/compact":                     {},
	"golang.org/x/text/internal/number":                               {},
	"golang.org/x/text/internal/stringset":                            {},
	"golang.org/x/text/internal/tag":                                  {},
	"golang.org/x/text/internal/testtext":                             {},
	"golang.org/x/text/internal/triegen":                              {},
	"golang.org/x/text/internal/ucd":                                  {},
	"golang.org/x/text/internal/utf8internal":                         {},
	"golang.org/x/text/language":                                      {},
	"golang.org/x/text/language/display":                              {},
	"golang.org/x/text/message":                                       {},
	"golang.org/x/text/message/catalog":                               {},
	"golang.org/x/text/message/pipeline":                              {},
	"golang.org/x/text/number":                                        {},
	"golang.org/x/text/runes":                                         {},
	"golang.org/x/text/search":                                        {},
	"golang.org/x/text/secure":                                        {},
	"golang.org/x/text/secure/bidirule":                               {},
	"golang.org/x/text/secure/precis":                                 {},
	"golang.org/x/text/transform":                                     {},
	"golang.org/x/text/unicode":                                       {},
	"golang.org/x/text/unicode/bidi":                                  {},
	"golang.org/x/text/unicode/cldr":                                  {},
	"golang.org/x/text/unicode/norm":                                  {},
	"golang.org/x/text/unicode/rangetable":                            {},
	"golang.org/x/text/unicode/runenames":                             {},
	"golang.org/x/text/width":                                         {},
	"golang.org/x/time/rate":                                          {},
	"golang.org/x/tools/benchmark/parse":                              {},
	"golang.org/x/tools/blog":                                         {},
	"golang.org/x/tools/blog/atom":                                    {},
	"golang.org/x/tools/cmd/benchcmp":                                 {},
	"golang.org/x/tools/cmd/bundle":                                   {},
	"golang.org/x/tools/cmd/callgraph":                                {},
	"golang.org/x/tools/cmd/compilebench":                             {},
	"golang.org/x/tools/cmd/cover":                                    {},
	"golang.org/x/tools/cmd/digraph":                                  {},
	"golang.org/x/tools/cmd/eg":                                       {},
	"golang.org/x/tools/cmd/fiximports":                               {},
	"golang.org/x/tools/cmd/getgo":                                    {},
	"golang.org/x/tools/cmd/getgo/server":                             {},
	"golang.org/x/tools/cmd/go-contrib-init":                          {},
	"golang.org/x/tools/cmd/godex":                                    {},
	"golang.org/x/tools/cmd/godoc":                                    {},
	"golang.org/x/tools/cmd/goimports":                                {},
	"golang.org/x/tools/cmd/golsp":                                    {},
	"golang.org/x/tools/cmd/gomvpkg":                                  {},
	"golang.org/x/tools/cmd/gorename":                                 {},
	"golang.org/x/tools/cmd/gotype":                                   {},
	"golang.org/x/tools/cmd/goyacc":                                   {},
	"golang.org/x/tools/cmd/guru":                                     {},
	"golang.org/x/tools/cmd/guru/serial":                              {},
	"golang.org/x/tools/cmd/heapview":                                 {},
	"golang.org/x/tools/cmd/heapview/internal/core":                   {},
	"golang.org/x/tools/cmd/html2article":                             {},
	"golang.org/x/tools/cmd/present":                                  {},
	"golang.org/x/tools/cmd/ssadump":                                  {},
	"golang.org/x/tools/cmd/stress":                                   {},
	"golang.org/x/tools/cmd/stringer":                                 {},
	"golang.org/x/tools/cmd/tip":                                      {},
	"golang.org/x/tools/cmd/toolstash":                                {},
	"golang.org/x/tools/container/intsets":                            {},
	"golang.org/x/tools/cover":                                        {},
	"golang.org/x/tools/go/analysis":                                  {},
	"golang.org/x/tools/go/analysis/analysistest":                     {},
	"golang.org/x/tools/go/analysis/cmd/vet":                          {},
	"golang.org/x/tools/go/analysis/internal/analysisflags":           {},
	"golang.org/x/tools/go/analysis/internal/checker":                 {},
	"golang.org/x/tools/go/analysis/multichecker":                     {},
	"golang.org/x/tools/go/analysis/passes/asmdecl":                   {},
	"golang.org/x/tools/go/analysis/passes/assign":                    {},
	"golang.org/x/tools/go/analysis/passes/atomic":                    {},
	"golang.org/x/tools/go/analysis/passes/bools":                     {},
	"golang.org/x/tools/go/analysis/passes/buildssa":                  {},
	"golang.org/x/tools/go/analysis/passes/buildtag":                  {},
	"golang.org/x/tools/go/analysis/passes/cgocall":                   {},
	"golang.org/x/tools/go/analysis/passes/composite":                 {},
	"golang.org/x/tools/go/analysis/passes/copylock":                  {},
	"golang.org/x/tools/go/analysis/passes/ctrlflow":                  {},
	"golang.org/x/tools/go/analysis/passes/findcall":                  {},
	"golang.org/x/tools/go/analysis/passes/findcall/cmd/findcall":     {},
	"golang.org/x/tools/go/analysis/passes/httpresponse":              {},
	"golang.org/x/tools/go/analysis/passes/inspect":                   {},
	"golang.org/x/tools/go/analysis/passes/internal/analysisutil":     {},
	"golang.org/x/tools/go/analysis/passes/loopclosure":               {},
	"golang.org/x/tools/go/analysis/passes/lostcancel":                {},
	"golang.org/x/tools/go/analysis/passes/lostcancel/cmd/lostcancel": {},
	"golang.org/x/tools/go/analysis/passes/nilfunc":                   {},
	"golang.org/x/tools/go/analysis/passes/nilness":                   {},
	"golang.org/x/tools/go/analysis/passes/nilness/cmd/nilness":       {},
	"golang.org/x/tools/go/analysis/passes/pkgfact":                   {},
	"golang.org/x/tools/go/analysis/passes/printf":                    {},
	"golang.org/x/tools/go/analysis/passes/shadow":                    {},
	"golang.org/x/tools/go/analysis/passes/shift":                     {},
	"golang.org/x/tools/go/analysis/passes/stdmethods":                {},
	"golang.org/x/tools/go/analysis/passes/structtag":                 {},
	"golang.org/x/tools/go/analysis/passes/tests":                     {},
	"golang.org/x/tools/go/analysis/passes/unreachable":               {},
	"golang.org/x/tools/go/analysis/passes/unsafeptr":                 {},
	"golang.org/x/tools/go/analysis/passes/unusedresult":              {},
	"golang.org/x/tools/go/analysis/singlechecker":                    {},
	"golang.org/x/tools/go/ast/astutil":                               {},
	"golang.org/x/tools/go/ast/inspector":                             {},
	"golang.org/x/tools/go/buildutil":                                 {},
	"golang.org/x/tools/go/callgraph":                                 {},
	"golang.org/x/tools/go/callgraph/cha":                             {},
	"golang.org/x/tools/go/callgraph/rta":                             {},
	"golang.org/x/tools/go/callgraph/static":                          {},
	"golang.org/x/tools/go/cfg":                                       {},
	"golang.org/x/tools/go/gccgoexportdata":                           {},
	"golang.org/x/tools/go/gcexportdata":                              {},
	"golang.org/x/tools/go/internal/cgo":                              {},
	"golang.org/x/tools/go/internal/gccgoimporter":                    {},
	"golang.org/x/tools/go/internal/gcimporter":                       {},
	"golang.org/x/tools/go/loader":                                    {},
	"golang.org/x/tools/go/packages":                                  {},
	"golang.org/x/tools/go/packages/gopackages":                       {},
	"golang.org/x/tools/go/packages/packagestest":                     {},
	"golang.org/x/tools/go/pointer":                                   {},
	"golang.org/x/tools/go/ssa":                                       {},
	"golang.org/x/tools/go/ssa/interp":                                {},
	"golang.org/x/tools/go/ssa/ssautil":                               {},
	"golang.org/x/tools/go/types/objectpath":                          {},
	"golang.org/x/tools/go/types/typeutil":                            {},
	"golang.org/x/tools/go/vcs":                                       {},
	"golang.org/x/tools/godoc":                                        {},
	"golang.org/x/tools/godoc/analysis":                               {},
	"golang.org/x/tools/godoc/dl":                                     {},
	"golang.org/x/tools/godoc/env":                                    {},
	"golang.org/x/tools/godoc/proxy":                                  {},
	"golang.org/x/tools/godoc/redirect":                               {},
	"golang.org/x/tools/godoc/short":                                  {},
	"golang.org/x/tools/godoc/static":                                 {},
	"golang.org/x/tools/godoc/util":                                   {},
	"golang.org/x/tools/godoc/vfs":                                    {},
	"golang.org/x/tools/godoc/vfs/gatefs":                             {},
	"golang.org/x/tools/godoc/vfs/httpfs":                             {},
	"golang.org/x/tools/godoc/vfs/mapfs":                              {},
	"golang.org/x/tools/godoc/vfs/zipfs":                              {},
	"golang.org/x/tools/imports":                                      {},
	"golang.org/x/tools/internal/fastwalk":                            {},
	"golang.org/x/tools/internal/gopathwalk":                          {},
	"golang.org/x/tools/internal/jsonrpc2":                            {},
	"golang.org/x/tools/internal/lsp":                                 {},
	"golang.org/x/tools/internal/lsp/protocol":                        {},
	"golang.org/x/tools/internal/semver":                              {},
	"golang.org/x/tools/playground":                                   {},
	"golang.org/x/tools/playground/socket":                            {},
	"golang.org/x/tools/present":                                      {},
	"golang.org/x/tools/refactor/eg":                                  {},
	"golang.org/x/tools/refactor/importgraph":                         {},
	"golang.org/x/tools/refactor/rename":                              {},
	"golang.org/x/tools/refactor/satisfy":                             {},
	"golang.org/x/tour":                                               {},
	"golang.org/x/tour/content":                                       {},
	"golang.org/x/tour/gotour":                                        {},
	"golang.org/x/tour/pic":                                           {},
	"golang.org/x/tour/reader":                                        {},
	"golang.org/x/tour/tree":                                          {},
	"golang.org/x/tour/wc":                                            {},
	"golang.org/x/vgo":                                                {},
// subTree looks non-recursively for a directory with the given name in t,
// and returns the corresponding tree.
// If a directory with such name doesn't exist in t, it returns os.ErrNotExist.
func subTree(r *git.Repository, t *object.Tree, name string) (*object.Tree, error) {
	for _, e := range t.Entries {
		if e.Name != name {
			continue
		}
		return r.TreeObject(e.Hash)
	}
	return nil, os.ErrNotExist
}

// expandPattern returns a list of Go packages matched by specified
// import path pattern, which may have the following forms:
//
service.go
@@ -2,11 +2,10 @@ package main

import (
	"context"
	"fmt"
	"log"
	"path"
	"sort"
	"strings"
	"sync"
	"time"

@@ -73,19 +72,12 @@ func newService(ctx context.Context) *service {

func emptyDirectories() map[string]*Directory {
	// Initialize places for issues and changes, using existing packages
	// and their parent directories.
	issuesAndChanges := make(map[string]*Directory)
	for p := range existingPackages {
		elems := strings.Split(p, "/")
		for i := len(elems); i >= 1; i-- { // Iterate in reverse order so we can break out early.
			p := path.Join(elems[:i]...)
			if _, ok := issuesAndChanges[p]; ok {
				break
			}
			issuesAndChanges[p] = new(Directory)
		}
	for d := range existingDirectories {
		issuesAndChanges[d] = new(Directory)
	}
	issuesAndChanges[otherPackages] = new(Directory)
	return issuesAndChanges
}

@@ -313,14 +305,17 @@ var gerritProjects = map[string]string{
	"go.googlesource.com/benchmarks": "golang.org/x/benchmarks",
	"go.googlesource.com/blog":       "golang.org/x/blog",
	"go.googlesource.com/build":      "golang.org/x/build",
	"go.googlesource.com/crypto":     "golang.org/x/crypto",
	"go.googlesource.com/debug":      "golang.org/x/debug",
	"go.googlesource.com/dl":         "golang.org/dl",
	"go.googlesource.com/example":    "golang.org/x/example",
	"go.googlesource.com/exp":        "golang.org/x/exp",
	"go.googlesource.com/image":      "golang.org/x/image",
	"go.googlesource.com/lint":       "golang.org/x/lint",
	"go.googlesource.com/mobile":     "golang.org/x/mobile",
	"go.googlesource.com/mod":        "golang.org/x/mod",
	"go.googlesource.com/net":        "golang.org/x/net",
	"go.googlesource.com/oauth2":     "golang.org/x/oauth2",
	"go.googlesource.com/perf":       "golang.org/x/perf",
	"go.googlesource.com/playground": "golang.org/x/playground",
	"go.googlesource.com/review":     "golang.org/x/review",
@@ -331,10 +326,12 @@ var gerritProjects = map[string]string{
	"go.googlesource.com/text":       "golang.org/x/text",
	"go.googlesource.com/time":       "golang.org/x/time",
	"go.googlesource.com/tools":      "golang.org/x/tools",
	"go.googlesource.com/tour":       "golang.org/x/tour",
	"go.googlesource.com/vgo":        "golang.org/x/vgo",
	"go.googlesource.com/website":    "golang.org/x/website",
	"go.googlesource.com/xerrors":    "golang.org/x/xerrors",
}

const otherPackages = "other"

// ImportPathToFullPrefix returns the an issue title prefix (including ": ") for the given import path.