mirror of
https://github.com/golang/go.git
synced 2025-11-01 09:10:57 +00:00
cmd/api: eliminate duplicate package import work
On my Mac, cuts the API checks from 15 seconds to 6 seconds. Also clean up some tag confusion: go run list-of-files ignores tags. R=bradfitz, gri CC=golang-dev https://golang.org/cl/12699048
This commit is contained in:
parent
1f25f5ad48
commit
b78410bda1
4 changed files with 60 additions and 6 deletions
|
|
@ -1,9 +1,9 @@
|
||||||
// +build api_tool
|
|
||||||
|
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build api_tool
|
||||||
|
|
||||||
// Binary api computes the exported API of a set of Go packages.
|
// Binary api computes the exported API of a set of Go packages.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
@ -387,6 +387,38 @@ func contains(list []string, s string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pkgCache = map[string]*types.Package{} // map tagKey to package
|
||||||
|
pkgTags = map[string][]string{} // map import dir to list of relevant tags
|
||||||
|
)
|
||||||
|
|
||||||
|
// tagKey returns the tag-based key to use in the pkgCache.
|
||||||
|
// It is a comma-separated string; the first part is dir, the rest tags.
|
||||||
|
// The satisfied tags are derived from context but only those that
|
||||||
|
// matter (the ones listed in the tags argument) are used.
|
||||||
|
// The tags list, which came from go/build's Package.AllTags,
|
||||||
|
// is known to be sorted.
|
||||||
|
func tagKey(dir string, context *build.Context, tags []string) string {
|
||||||
|
ctags := map[string]bool{
|
||||||
|
context.GOOS: true,
|
||||||
|
context.GOARCH: true,
|
||||||
|
}
|
||||||
|
if context.CgoEnabled {
|
||||||
|
ctags["cgo"] = true
|
||||||
|
}
|
||||||
|
for _, tag := range context.BuildTags {
|
||||||
|
ctags[tag] = true
|
||||||
|
}
|
||||||
|
// TODO: ReleaseTags (need to load default)
|
||||||
|
key := dir
|
||||||
|
for _, tag := range tags {
|
||||||
|
if ctags[tag] {
|
||||||
|
key += "," + tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
// Importing is a sentinel taking the place in Walker.imported
|
// Importing is a sentinel taking the place in Walker.imported
|
||||||
// for a package that is in the process of being imported.
|
// for a package that is in the process of being imported.
|
||||||
var importing types.Package
|
var importing types.Package
|
||||||
|
|
@ -411,6 +443,19 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
|
||||||
if context == nil {
|
if context == nil {
|
||||||
context = &build.Default
|
context = &build.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look in cache.
|
||||||
|
// If we've already done an import with the same set
|
||||||
|
// of relevant tags, reuse the result.
|
||||||
|
var key string
|
||||||
|
if tags, ok := pkgTags[dir]; ok {
|
||||||
|
key = tagKey(dir, context, tags)
|
||||||
|
if pkg := pkgCache[key]; pkg != nil {
|
||||||
|
w.imported[name] = pkg
|
||||||
|
return pkg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info, err := context.ImportDir(dir, 0)
|
info, err := context.ImportDir(dir, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, nogo := err.(*build.NoGoError); nogo {
|
if _, nogo := err.(*build.NoGoError); nogo {
|
||||||
|
|
@ -418,6 +463,13 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
|
||||||
}
|
}
|
||||||
log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err)
|
log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save tags list first time we see a directory.
|
||||||
|
if _, ok := pkgTags[dir]; !ok {
|
||||||
|
pkgTags[dir] = info.AllTags
|
||||||
|
key = tagKey(dir, context, info.AllTags)
|
||||||
|
}
|
||||||
|
|
||||||
filenames := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
|
filenames := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
|
||||||
|
|
||||||
// Certain files only exist when building for the specified context.
|
// Certain files only exist when building for the specified context.
|
||||||
|
|
@ -463,6 +515,8 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
|
||||||
log.Fatalf("error typechecking package %s: %s (%s)", name, err, ctxt)
|
log.Fatalf("error typechecking package %s: %s (%s)", name, err, ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkgCache[key] = pkg
|
||||||
|
|
||||||
w.imported[name] = pkg
|
w.imported[name] = pkg
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// +build from_src_run
|
|
||||||
|
|
||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
// The run program is invoked via "go run" from src/run.bash or
|
// The run program is invoked via "go run" from src/run.bash or
|
||||||
// src/run.bat conditionally builds and runs the cmd/api tool.
|
// src/run.bat conditionally builds and runs the cmd/api tool.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ time go run run.go || exit 1
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '# Checking API compatibility.'
|
echo '# Checking API compatibility.'
|
||||||
go run --tags=from_src_run $GOROOT/src/cmd/api/run.go
|
time go run $GOROOT/src/cmd/api/run.go
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo ALL TESTS PASSED
|
echo ALL TESTS PASSED
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ set GOMAXPROCS=%OLDGOMAXPROCS%
|
||||||
set OLDGOMAXPROCS=
|
set OLDGOMAXPROCS=
|
||||||
|
|
||||||
echo # Checking API compatibility.
|
echo # Checking API compatibility.
|
||||||
go run --tags=from_src_run "%GOROOT%\src\cmd\api\run.go"
|
go run "%GOROOT%\src\cmd\api\run.go"
|
||||||
if errorlevel 1 goto fail
|
if errorlevel 1 goto fail
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue