wire/internal/wire: use on-disk GOPATH in generate tests (google/go-cloud#616)
The primary motivation is to permit a move to using go/packages instead of go/loader. go/packages runs exclusively by shelling out to the go tool, which precludes use of the in-memory "magic" GOPATH being used up to this point. This has a secondary effect of removing a lot of code to support "magic" GOPATH from the test infrastructure. This is on the whole good, but necessitated a change in the error scrubbing: since the filenames are no longer fixed, error scrubbing also must remove the leading $GOPATH/src lines. Another related change: since all callers of Generate needed to know the package path in order to write out wire_gen.go (necessitating a find-only import search) and Generate already has this information, Generate now returns this information to the caller. This should further reduce callers' coupling to Wire's load internals. It also eliminates code duplication. This should hopefully shake out any difference in path separators for running on Windows, but I have not tested that yet. Updates google/go-cloud#78 Updates google/go-cloud#323
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
@@ -190,11 +191,19 @@ type Value struct {
|
||||
info *types.Info
|
||||
}
|
||||
|
||||
// Load finds all the provider sets in the given packages, as well as
|
||||
// the provider sets' transitive dependencies. It may return both errors
|
||||
// and Info.
|
||||
func Load(bctx *build.Context, wd string, pkgs []string) (*Info, []error) {
|
||||
prog, errs := load(bctx, wd, pkgs)
|
||||
// Load finds all the provider sets in the packages that match the given
|
||||
// patterns, as well as the provider sets' transitive dependencies. It
|
||||
// may return both errors and Info. The patterns are defined by the
|
||||
// underlying build system. For the go tool, this is described at
|
||||
// https://golang.org/cmd/go/#hdr-Package_lists_and_patterns
|
||||
//
|
||||
// wd is the working directory and env is the set of environment
|
||||
// variables to use when loading the packages specified by patterns. If
|
||||
// env is nil or empty, it is interpreted as an empty set of variables.
|
||||
// In case of duplicate environment variables, the last one in the list
|
||||
// takes precedence.
|
||||
func Load(ctx context.Context, wd string, env []string, patterns []string) (*Info, []error) {
|
||||
prog, errs := load(ctx, wd, env, patterns)
|
||||
if len(errs) > 0 {
|
||||
return nil, errs
|
||||
}
|
||||
@@ -275,12 +284,22 @@ func Load(bctx *build.Context, wd string, pkgs []string) (*Info, []error) {
|
||||
return info, ec.errors
|
||||
}
|
||||
|
||||
// load typechecks the packages, including function body type checking
|
||||
// for the packages directly named.
|
||||
func load(bctx *build.Context, wd string, pkgs []string) (*loader.Program, []error) {
|
||||
// load typechecks the packages that match the given patterns, including
|
||||
// function body type checking for the packages that directly match. The
|
||||
// patterns are defined by the underlying build system. For the go tool,
|
||||
// this is described at
|
||||
// https://golang.org/cmd/go/#hdr-Package_lists_and_patterns
|
||||
//
|
||||
// wd is the working directory and env is the set of environment
|
||||
// variables to use when loading the packages specified by patterns. If
|
||||
// env is nil or empty, it is interpreted as an empty set of variables.
|
||||
// In case of duplicate environment variables, the last one in the list
|
||||
// takes precedence.
|
||||
func load(ctx context.Context, wd string, env []string, patterns []string) (*loader.Program, []error) {
|
||||
bctx := buildContextFromEnv(env)
|
||||
var foundPkgs []*build.Package
|
||||
ec := new(errorCollector)
|
||||
for _, name := range pkgs {
|
||||
for _, name := range patterns {
|
||||
p, err := bctx.Import(name, wd, build.FindOnly)
|
||||
if err != nil {
|
||||
ec.add(err)
|
||||
@@ -320,7 +339,7 @@ func load(bctx *build.Context, wd string, pkgs []string) (*loader.Program, []err
|
||||
return pkg, err
|
||||
},
|
||||
}
|
||||
for _, name := range pkgs {
|
||||
for _, name := range patterns {
|
||||
conf.Import(name)
|
||||
}
|
||||
|
||||
@@ -334,6 +353,35 @@ func load(bctx *build.Context, wd string, pkgs []string) (*loader.Program, []err
|
||||
return prog, nil
|
||||
}
|
||||
|
||||
func buildContextFromEnv(env []string) *build.Context {
|
||||
// TODO(#78): Remove this function in favor of using go/packages,
|
||||
// which does not need a *build.Context.
|
||||
|
||||
getenv := func(name string) string {
|
||||
for i := len(env) - 1; i >= 0; i-- {
|
||||
if strings.HasPrefix(env[i], name+"=") {
|
||||
return env[i][len(name)+1:]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
bctx := new(build.Context)
|
||||
*bctx = build.Default
|
||||
if v := getenv("GOARCH"); v != "" {
|
||||
bctx.GOARCH = v
|
||||
}
|
||||
if v := getenv("GOOS"); v != "" {
|
||||
bctx.GOOS = v
|
||||
}
|
||||
if v := getenv("GOROOT"); v != "" {
|
||||
bctx.GOROOT = v
|
||||
}
|
||||
if v := getenv("GOPATH"); v != "" {
|
||||
bctx.GOPATH = v
|
||||
}
|
||||
return bctx
|
||||
}
|
||||
|
||||
func importPathInPkgList(pkgs []*build.Package, path string) bool {
|
||||
for _, p := range pkgs {
|
||||
if path == p.ImportPath {
|
||||
|
||||
Reference in New Issue
Block a user