go/packages: remove DepOnly from the raw package
All the other members of raw package are stable for any given package, DepOnly relates to the query patterns, not thepackages. Instead the raw functions now return the set of roots matched Other minor changes included: rawConfig.ExtraFlags -> rawConfig.Flags delete rawConfig.Context Change-Id: I3a729fa4557043f65da386eed94ab46fdfacb8ad Reviewed-on: https://go-review.googlesource.com/127035 Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
33176b2029
commit
7ebc57ba19
|
@ -8,6 +8,7 @@ package packages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
@ -52,7 +53,7 @@ type jsonPackage struct {
|
||||||
// golistPackages uses the "go list" command to expand the
|
// golistPackages uses the "go list" command to expand the
|
||||||
// pattern words and return metadata for the specified packages.
|
// pattern words and return metadata for the specified packages.
|
||||||
// dir may be "" and env may be nil, as per os/exec.Command.
|
// dir may be "" and env may be nil, as per os/exec.Command.
|
||||||
func golistPackages(cfg *rawConfig, words ...string) ([]*rawPackage, error) {
|
func golistPackages(ctx context.Context, cfg *rawConfig, words ...string) ([]string, []*rawPackage, error) {
|
||||||
// go list uses the following identifiers in ImportPath and Imports:
|
// go list uses the following identifiers in ImportPath and Imports:
|
||||||
//
|
//
|
||||||
// "p" -- importable package or main (command)
|
// "p" -- importable package or main (command)
|
||||||
|
@ -67,16 +68,17 @@ func golistPackages(cfg *rawConfig, words ...string) ([]*rawPackage, error) {
|
||||||
// Run "go list" for complete
|
// Run "go list" for complete
|
||||||
// information on the specified packages.
|
// information on the specified packages.
|
||||||
|
|
||||||
buf, err := golist(cfg, golistargs(cfg, words))
|
buf, err := golist(ctx, cfg, golistargs(cfg, words))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
// Decode the JSON and convert it to rawPackage form.
|
// Decode the JSON and convert it to rawPackage form.
|
||||||
|
var roots []string
|
||||||
var result []*rawPackage
|
var result []*rawPackage
|
||||||
for dec := json.NewDecoder(buf); dec.More(); {
|
for dec := json.NewDecoder(buf); dec.More(); {
|
||||||
p := new(jsonPackage)
|
p := new(jsonPackage)
|
||||||
if err := dec.Decode(p); err != nil {
|
if err := dec.Decode(p); err != nil {
|
||||||
return nil, fmt.Errorf("JSON decoding failed: %v", err)
|
return nil, nil, fmt.Errorf("JSON decoding failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad package?
|
// Bad package?
|
||||||
|
@ -159,12 +161,14 @@ func golistPackages(cfg *rawConfig, words ...string) ([]*rawPackage, error) {
|
||||||
PkgPath: pkgpath,
|
PkgPath: pkgpath,
|
||||||
Imports: imports,
|
Imports: imports,
|
||||||
Export: export,
|
Export: export,
|
||||||
DepOnly: p.DepOnly,
|
}
|
||||||
|
if !p.DepOnly {
|
||||||
|
roots = append(roots, pkg.ID)
|
||||||
}
|
}
|
||||||
result = append(result, pkg)
|
result = append(result, pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return roots, result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// absJoin absolutizes and flattens the lists of files.
|
// absJoin absolutizes and flattens the lists of files.
|
||||||
|
@ -181,17 +185,22 @@ func absJoin(dir string, fileses ...[]string) (res []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func golistargs(cfg *rawConfig, words []string) []string {
|
func golistargs(cfg *rawConfig, words []string) []string {
|
||||||
fullargs := []string{"list", "-e", "-json", "-cgo=true"}
|
fullargs := []string{
|
||||||
fullargs = append(fullargs, cfg.Flags()...)
|
"list", "-e", "-json", "-cgo=true",
|
||||||
|
fmt.Sprintf("-test=%t", cfg.Tests),
|
||||||
|
fmt.Sprintf("-export=%t", cfg.Export),
|
||||||
|
fmt.Sprintf("-deps=%t", cfg.Deps),
|
||||||
|
}
|
||||||
|
fullargs = append(fullargs, cfg.Flags...)
|
||||||
fullargs = append(fullargs, "--")
|
fullargs = append(fullargs, "--")
|
||||||
fullargs = append(fullargs, words...)
|
fullargs = append(fullargs, words...)
|
||||||
return fullargs
|
return fullargs
|
||||||
}
|
}
|
||||||
|
|
||||||
// golist returns the JSON-encoded result of a "go list args..." query.
|
// golist returns the JSON-encoded result of a "go list args..." query.
|
||||||
func golist(cfg *rawConfig, args []string) (*bytes.Buffer, error) {
|
func golist(ctx context.Context, cfg *rawConfig, args []string) (*bytes.Buffer, error) {
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
cmd := exec.CommandContext(cfg.Context, "go", args...)
|
cmd := exec.CommandContext(ctx, "go", args...)
|
||||||
cmd.Env = cfg.Env
|
cmd.Env = cfg.Env
|
||||||
cmd.Dir = cfg.Dir
|
cmd.Dir = cfg.Dir
|
||||||
cmd.Stdout = out
|
cmd.Stdout = out
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package packages
|
package packages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
@ -18,19 +19,21 @@ import (
|
||||||
|
|
||||||
// TODO(matloob): Support cgo. Copy code from the loader that runs cgo.
|
// TODO(matloob): Support cgo. Copy code from the loader that runs cgo.
|
||||||
|
|
||||||
func golistPackagesFallback(cfg *rawConfig, words ...string) ([]*rawPackage, error) {
|
func golistPackagesFallback(ctx context.Context, cfg *rawConfig, words ...string) ([]string, []*rawPackage, error) {
|
||||||
original, deps, err := getDeps(cfg, words...)
|
original, deps, err := getDeps(ctx, cfg, words...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []*rawPackage
|
var result []*rawPackage
|
||||||
|
var roots []string
|
||||||
addPackage := func(p *jsonPackage) {
|
addPackage := func(p *jsonPackage) {
|
||||||
if p.Name == "" {
|
if p.Name == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id := p.ImportPath
|
id := p.ImportPath
|
||||||
|
isRoot := original[id] != nil
|
||||||
pkgpath := id
|
pkgpath := id
|
||||||
|
|
||||||
if pkgpath == "unsafe" {
|
if pkgpath == "unsafe" {
|
||||||
|
@ -53,7 +56,9 @@ func golistPackagesFallback(cfg *rawConfig, words ...string) ([]*rawPackage, err
|
||||||
}
|
}
|
||||||
return importMap
|
return importMap
|
||||||
}
|
}
|
||||||
|
if isRoot {
|
||||||
|
roots = append(roots, id)
|
||||||
|
}
|
||||||
result = append(result, &rawPackage{
|
result = append(result, &rawPackage{
|
||||||
ID: id,
|
ID: id,
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
|
@ -61,11 +66,13 @@ func golistPackagesFallback(cfg *rawConfig, words ...string) ([]*rawPackage, err
|
||||||
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
|
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
|
||||||
PkgPath: pkgpath,
|
PkgPath: pkgpath,
|
||||||
Imports: importMap(p.Imports),
|
Imports: importMap(p.Imports),
|
||||||
DepOnly: original[id] == nil,
|
|
||||||
})
|
})
|
||||||
if cfg.Tests {
|
if cfg.Tests {
|
||||||
testID := fmt.Sprintf("%s [%s.test]", id, id)
|
testID := fmt.Sprintf("%s [%s.test]", id, id)
|
||||||
if len(p.TestGoFiles) > 0 || len(p.XTestGoFiles) > 0 {
|
if len(p.TestGoFiles) > 0 || len(p.XTestGoFiles) > 0 {
|
||||||
|
if isRoot {
|
||||||
|
roots = append(roots, testID)
|
||||||
|
}
|
||||||
result = append(result, &rawPackage{
|
result = append(result, &rawPackage{
|
||||||
ID: testID,
|
ID: testID,
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
|
@ -73,17 +80,19 @@ func golistPackagesFallback(cfg *rawConfig, words ...string) ([]*rawPackage, err
|
||||||
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
|
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
|
||||||
PkgPath: pkgpath,
|
PkgPath: pkgpath,
|
||||||
Imports: importMap(append(p.Imports, p.TestImports...)),
|
Imports: importMap(append(p.Imports, p.TestImports...)),
|
||||||
DepOnly: original[id] == nil,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if len(p.XTestGoFiles) > 0 {
|
if len(p.XTestGoFiles) > 0 {
|
||||||
|
xtestID := fmt.Sprintf("%s_test [%s.test]", id, id)
|
||||||
|
if isRoot {
|
||||||
|
roots = append(roots, xtestID)
|
||||||
|
}
|
||||||
result = append(result, &rawPackage{
|
result = append(result, &rawPackage{
|
||||||
ID: fmt.Sprintf("%s_test [%s.test]", id, id),
|
ID: xtestID,
|
||||||
Name: p.Name + "_test",
|
Name: p.Name + "_test",
|
||||||
GoFiles: absJoin(p.Dir, p.XTestGoFiles),
|
GoFiles: absJoin(p.Dir, p.XTestGoFiles),
|
||||||
PkgPath: pkgpath,
|
PkgPath: pkgpath,
|
||||||
Imports: importMap(append(p.XTestImports, testID)),
|
Imports: importMap(append(p.XTestImports, testID)),
|
||||||
DepOnly: original[id] == nil,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,30 +102,30 @@ func golistPackagesFallback(cfg *rawConfig, words ...string) ([]*rawPackage, err
|
||||||
addPackage(pkg)
|
addPackage(pkg)
|
||||||
}
|
}
|
||||||
if !cfg.Deps || len(deps) == 0 {
|
if !cfg.Deps || len(deps) == 0 {
|
||||||
return result, nil
|
return roots, result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := golist(cfg, golistargs_fallback(cfg, deps))
|
buf, err := golist(ctx, cfg, golistargs_fallback(cfg, deps))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the JSON and convert it to rawPackage form.
|
// Decode the JSON and convert it to rawPackage form.
|
||||||
for dec := json.NewDecoder(buf); dec.More(); {
|
for dec := json.NewDecoder(buf); dec.More(); {
|
||||||
p := new(jsonPackage)
|
p := new(jsonPackage)
|
||||||
if err := dec.Decode(p); err != nil {
|
if err := dec.Decode(p); err != nil {
|
||||||
return nil, fmt.Errorf("JSON decoding failed: %v", err)
|
return nil, nil, fmt.Errorf("JSON decoding failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addPackage(p)
|
addPackage(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return roots, result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDeps runs an initial go list to determine all the dependency packages.
|
// getDeps runs an initial go list to determine all the dependency packages.
|
||||||
func getDeps(cfg *rawConfig, words ...string) (originalSet map[string]*jsonPackage, deps []string, err error) {
|
func getDeps(ctx context.Context, cfg *rawConfig, words ...string) (originalSet map[string]*jsonPackage, deps []string, err error) {
|
||||||
buf, err := golist(cfg, golistargs_fallback(cfg, words))
|
buf, err := golist(ctx, cfg, golistargs_fallback(cfg, words))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -149,7 +158,7 @@ func getDeps(cfg *rawConfig, words ...string) (originalSet map[string]*jsonPacka
|
||||||
|
|
||||||
func golistargs_fallback(cfg *rawConfig, words []string) []string {
|
func golistargs_fallback(cfg *rawConfig, words []string) []string {
|
||||||
fullargs := []string{"list", "-e", "-json"}
|
fullargs := []string{"list", "-e", "-json"}
|
||||||
fullargs = append(fullargs, cfg.ExtraFlags...)
|
fullargs = append(fullargs, cfg.Flags...)
|
||||||
fullargs = append(fullargs, "--")
|
fullargs = append(fullargs, "--")
|
||||||
fullargs = append(fullargs, words...)
|
fullargs = append(fullargs, words...)
|
||||||
return fullargs
|
return fullargs
|
||||||
|
|
|
@ -295,10 +295,10 @@ func (ld *loader) load(patterns ...string) ([]*Package, error) {
|
||||||
listfunc := golistPackages
|
listfunc := golistPackages
|
||||||
// TODO(matloob): Patterns may now be empty, if it was solely comprised of contains: patterns.
|
// TODO(matloob): Patterns may now be empty, if it was solely comprised of contains: patterns.
|
||||||
// See if the extra process invocation can be avoided.
|
// See if the extra process invocation can be avoided.
|
||||||
list, err := listfunc(rawCfg, patterns...)
|
roots, list, err := listfunc(ld.Context, rawCfg, patterns...)
|
||||||
if _, ok := err.(GoTooOldError); ok {
|
if _, ok := err.(GoTooOldError); ok {
|
||||||
listfunc = golistPackagesFallback
|
listfunc = golistPackagesFallback
|
||||||
list, err = listfunc(rawCfg, patterns...)
|
roots, list, err = listfunc(ld.Context, rawCfg, patterns...)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -315,7 +315,7 @@ func (ld *loader) load(patterns ...string) ([]*Package, error) {
|
||||||
// TODO(matloob): Do only one query per directory.
|
// TODO(matloob): Do only one query per directory.
|
||||||
fdir := filepath.Dir(f)
|
fdir := filepath.Dir(f)
|
||||||
rawCfg.Dir = fdir
|
rawCfg.Dir = fdir
|
||||||
cList, err := listfunc(rawCfg, ".")
|
_, cList, err := listfunc(ld.Context, rawCfg, ".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -327,10 +327,9 @@ func (ld *loader) load(patterns ...string) ([]*Package, error) {
|
||||||
}
|
}
|
||||||
seenPkgs[pkg.ID] = true
|
seenPkgs[pkg.ID] = true
|
||||||
dedupedList = append(dedupedList, pkg)
|
dedupedList = append(dedupedList, pkg)
|
||||||
pkg.DepOnly = true
|
|
||||||
for _, pkgFile := range pkg.GoFiles {
|
for _, pkgFile := range pkg.GoFiles {
|
||||||
if filepath.Base(f) == filepath.Base(pkgFile) {
|
if filepath.Base(f) == filepath.Base(pkgFile) {
|
||||||
pkg.DepOnly = false
|
roots = append(roots, pkg.ID)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,12 +337,17 @@ func (ld *loader) load(patterns ...string) ([]*Package, error) {
|
||||||
list = append(list, dedupedList...)
|
list = append(list, dedupedList...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ld.loadFrom(list...)
|
return ld.loadFrom(roots, list...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ld *loader) loadFrom(list ...*rawPackage) ([]*Package, error) {
|
func (ld *loader) loadFrom(roots []string, list ...*rawPackage) ([]*Package, error) {
|
||||||
|
if len(list) == 0 {
|
||||||
|
return nil, fmt.Errorf("packages not found")
|
||||||
|
}
|
||||||
|
if len(roots) == 0 {
|
||||||
|
return nil, fmt.Errorf("packages had no initial set")
|
||||||
|
}
|
||||||
ld.pkgs = make(map[string]*loaderPackage, len(list))
|
ld.pkgs = make(map[string]*loaderPackage, len(list))
|
||||||
var initial []*loaderPackage
|
|
||||||
// first pass, fixup and build the map and roots
|
// first pass, fixup and build the map and roots
|
||||||
for _, pkg := range list {
|
for _, pkg := range list {
|
||||||
lpkg := &loaderPackage{
|
lpkg := &loaderPackage{
|
||||||
|
@ -357,18 +361,19 @@ func (ld *loader) loadFrom(list ...*rawPackage) ([]*Package, error) {
|
||||||
needsrc: ld.Mode >= LoadAllSyntax || pkg.Export == "",
|
needsrc: ld.Mode >= LoadAllSyntax || pkg.Export == "",
|
||||||
}
|
}
|
||||||
ld.pkgs[lpkg.ID] = lpkg
|
ld.pkgs[lpkg.ID] = lpkg
|
||||||
if !pkg.DepOnly {
|
}
|
||||||
initial = append(initial, lpkg)
|
// check all the roots were found
|
||||||
if ld.Mode == LoadSyntax {
|
initial := make([]*loaderPackage, len(roots))
|
||||||
lpkg.needsrc = true
|
for i, root := range roots {
|
||||||
}
|
lpkg := ld.pkgs[root]
|
||||||
|
if lpkg == nil {
|
||||||
|
return nil, fmt.Errorf("root package %v not found", root)
|
||||||
|
}
|
||||||
|
initial[i] = lpkg
|
||||||
|
// mark the roots as needing source
|
||||||
|
if ld.Mode == LoadSyntax {
|
||||||
|
lpkg.needsrc = true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if len(ld.pkgs) == 0 {
|
|
||||||
return nil, fmt.Errorf("packages not found")
|
|
||||||
}
|
|
||||||
if len(initial) == 0 {
|
|
||||||
return nil, fmt.Errorf("packages had no initial set")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Materialize the import graph.
|
// Materialize the import graph.
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
package packages
|
package packages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,37 +49,25 @@ type rawPackage struct {
|
||||||
// rawConfig specifies details about what raw package information is needed
|
// rawConfig specifies details about what raw package information is needed
|
||||||
// and how the underlying build tool should load package data.
|
// and how the underlying build tool should load package data.
|
||||||
type rawConfig struct {
|
type rawConfig struct {
|
||||||
Context context.Context
|
Dir string
|
||||||
Dir string
|
Env []string
|
||||||
Env []string
|
Flags []string
|
||||||
ExtraFlags []string
|
Export bool
|
||||||
Export bool
|
Tests bool
|
||||||
Tests bool
|
Deps bool
|
||||||
Deps bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRawConfig(cfg *Config) *rawConfig {
|
func newRawConfig(cfg *Config) *rawConfig {
|
||||||
rawCfg := &rawConfig{
|
rawCfg := &rawConfig{
|
||||||
Context: cfg.Context,
|
Dir: cfg.Dir,
|
||||||
Dir: cfg.Dir,
|
Env: cfg.Env,
|
||||||
Env: cfg.Env,
|
Flags: cfg.Flags,
|
||||||
ExtraFlags: cfg.Flags,
|
Export: cfg.Mode > LoadImports && cfg.Mode < LoadAllSyntax,
|
||||||
Export: cfg.Mode > LoadImports && cfg.Mode < LoadAllSyntax,
|
Tests: cfg.Tests,
|
||||||
Tests: cfg.Tests,
|
Deps: cfg.Mode >= LoadImports,
|
||||||
Deps: cfg.Mode >= LoadImports,
|
|
||||||
}
|
}
|
||||||
if rawCfg.Env == nil {
|
if rawCfg.Env == nil {
|
||||||
rawCfg.Env = os.Environ()
|
rawCfg.Env = os.Environ()
|
||||||
}
|
}
|
||||||
return rawCfg
|
return rawCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *rawConfig) Flags() []string {
|
|
||||||
return append([]string{
|
|
||||||
fmt.Sprintf("-test=%t", cfg.Tests),
|
|
||||||
fmt.Sprintf("-export=%t", cfg.Export),
|
|
||||||
fmt.Sprintf("-deps=%t", cfg.Deps),
|
|
||||||
},
|
|
||||||
cfg.ExtraFlags...,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue