Bumping k8s dependencies to 1.13
This commit is contained in:
328
vendor/golang.org/x/tools/go/packages/packagestest/expect.go
generated
vendored
Normal file
328
vendor/golang.org/x/tools/go/packages/packagestest/expect.go
generated
vendored
Normal file
@@ -0,0 +1,328 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package packagestest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/expect"
|
||||
)
|
||||
|
||||
const (
|
||||
markMethod = "mark"
|
||||
eofIdentifier = "EOF"
|
||||
)
|
||||
|
||||
// Expect invokes the supplied methods for all expectation notes found in
|
||||
// the exported source files.
|
||||
//
|
||||
// All exported go source files are parsed to collect the expectation
|
||||
// notes.
|
||||
// See the documentation for expect.Parse for how the notes are collected
|
||||
// and parsed.
|
||||
//
|
||||
// The methods are supplied as a map of name to function, and those functions
|
||||
// will be matched against the expectations by name.
|
||||
// Notes with no matching function will be skipped, and functions with no
|
||||
// matching notes will not be invoked.
|
||||
// If there are no registered markers yet, a special pass will be run first
|
||||
// which adds any markers declared with @mark(Name, pattern) or @name. These
|
||||
// call the Mark method to add the marker to the global set.
|
||||
// You can register the "mark" method to override these in your own call to
|
||||
// Expect. The bound Mark function is usable directly in your method map, so
|
||||
// exported.Expect(map[string]interface{}{"mark": exported.Mark})
|
||||
// replicates the built in behavior.
|
||||
//
|
||||
// Method invocation
|
||||
//
|
||||
// When invoking a method the expressions in the parameter list need to be
|
||||
// converted to values to be passed to the method.
|
||||
// There are a very limited set of types the arguments are allowed to be.
|
||||
// expect.Comment : passed the Comment instance being evaluated.
|
||||
// string : can be supplied either a string literal or an identifier.
|
||||
// int : can only be supplied an integer literal.
|
||||
// token.Pos : has a file position calculated as described below.
|
||||
// token.Position : has a file position calculated as described below.
|
||||
//
|
||||
// Position calculation
|
||||
//
|
||||
// There is some extra handling when a parameter is being coerced into a
|
||||
// token.Pos, token.Position or Range type argument.
|
||||
//
|
||||
// If the parameter is an identifier, it will be treated as the name of an
|
||||
// marker to look up (as if markers were global variables).
|
||||
//
|
||||
// If it is a string or regular expression, then it will be passed to
|
||||
// expect.MatchBefore to look up a match in the line at which it was declared.
|
||||
//
|
||||
// It is safe to call this repeatedly with different method sets, but it is
|
||||
// not safe to call it concurrently.
|
||||
func (e *Exported) Expect(methods map[string]interface{}) error {
|
||||
if err := e.getNotes(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.getMarkers(); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
ms := make(map[string]method, len(methods))
|
||||
for name, f := range methods {
|
||||
mi := method{f: reflect.ValueOf(f)}
|
||||
mi.converters = make([]converter, mi.f.Type().NumIn())
|
||||
for i := 0; i < len(mi.converters); i++ {
|
||||
mi.converters[i], err = e.buildConverter(mi.f.Type().In(i))
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid method %v: %v", name, err)
|
||||
}
|
||||
}
|
||||
ms[name] = mi
|
||||
}
|
||||
for _, n := range e.notes {
|
||||
if n.Args == nil {
|
||||
// simple identifier form, convert to a call to mark
|
||||
n = &expect.Note{
|
||||
Pos: n.Pos,
|
||||
Name: markMethod,
|
||||
Args: []interface{}{n.Name, n.Name},
|
||||
}
|
||||
}
|
||||
mi, ok := ms[n.Name]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
params := make([]reflect.Value, len(mi.converters))
|
||||
args := n.Args
|
||||
for i, convert := range mi.converters {
|
||||
params[i], args, err = convert(n, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", e.fset.Position(n.Pos), err)
|
||||
}
|
||||
}
|
||||
if len(args) > 0 {
|
||||
return fmt.Errorf("%v: unwanted args got %+v extra", e.fset.Position(n.Pos), args)
|
||||
}
|
||||
//TODO: catch the error returned from the method
|
||||
mi.f.Call(params)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Range struct {
|
||||
Start token.Pos
|
||||
End token.Pos
|
||||
}
|
||||
|
||||
// Mark adds a new marker to the known set.
|
||||
func (e *Exported) Mark(name string, r Range) {
|
||||
if e.markers == nil {
|
||||
e.markers = make(map[string]Range)
|
||||
}
|
||||
e.markers[name] = r
|
||||
}
|
||||
|
||||
func (e *Exported) getNotes() error {
|
||||
if e.notes != nil {
|
||||
return nil
|
||||
}
|
||||
notes := []*expect.Note{}
|
||||
for _, module := range e.written {
|
||||
for _, filename := range module {
|
||||
if !strings.HasSuffix(filename, ".go") {
|
||||
continue
|
||||
}
|
||||
l, err := expect.Parse(e.fset, filename, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to extract expectations: %v", err)
|
||||
}
|
||||
notes = append(notes, l...)
|
||||
}
|
||||
}
|
||||
e.notes = notes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Exported) getMarkers() error {
|
||||
if e.markers != nil {
|
||||
return nil
|
||||
}
|
||||
// set markers early so that we don't call getMarkers again from Expect
|
||||
e.markers = make(map[string]Range)
|
||||
return e.Expect(map[string]interface{}{
|
||||
markMethod: e.Mark,
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
noteType = reflect.TypeOf((*expect.Note)(nil))
|
||||
identifierType = reflect.TypeOf(expect.Identifier(""))
|
||||
posType = reflect.TypeOf(token.Pos(0))
|
||||
positionType = reflect.TypeOf(token.Position{})
|
||||
rangeType = reflect.TypeOf(Range{})
|
||||
)
|
||||
|
||||
// converter converts from a marker's argument parsed from the comment to
|
||||
// reflect values passed to the method during Invoke.
|
||||
// It takes the args remaining, and returns the args it did not consume.
|
||||
// This allows a converter to consume 0 args for well known types, or multiple
|
||||
// args for compound types.
|
||||
type converter func(*expect.Note, []interface{}) (reflect.Value, []interface{}, error)
|
||||
|
||||
// method is used to track information about Invoke methods that is expensive to
|
||||
// calculate so that we can work it out once rather than per marker.
|
||||
type method struct {
|
||||
f reflect.Value // the reflect value of the passed in method
|
||||
converters []converter // the parameter converters for the method
|
||||
}
|
||||
|
||||
// buildConverter works out what function should be used to go from an ast expressions to a reflect
|
||||
// value of the type expected by a method.
|
||||
// It is called when only the target type is know, it returns converters that are flexible across
|
||||
// all supported expression types for that target type.
|
||||
func (e *Exported) buildConverter(pt reflect.Type) (converter, error) {
|
||||
switch {
|
||||
case pt == noteType:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
return reflect.ValueOf(n), args, nil
|
||||
}, nil
|
||||
case pt == posType:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
r, remains, err := e.rangeConverter(n, args)
|
||||
if err != nil {
|
||||
return reflect.Value{}, nil, err
|
||||
}
|
||||
return reflect.ValueOf(r.Start), remains, nil
|
||||
}, nil
|
||||
case pt == positionType:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
r, remains, err := e.rangeConverter(n, args)
|
||||
if err != nil {
|
||||
return reflect.Value{}, nil, err
|
||||
}
|
||||
return reflect.ValueOf(e.fset.Position(r.Start)), remains, nil
|
||||
}, nil
|
||||
case pt == rangeType:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
r, remains, err := e.rangeConverter(n, args)
|
||||
if err != nil {
|
||||
return reflect.Value{}, nil, err
|
||||
}
|
||||
return reflect.ValueOf(r), remains, nil
|
||||
}, nil
|
||||
case pt == identifierType:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
switch arg := arg.(type) {
|
||||
case expect.Identifier:
|
||||
return reflect.ValueOf(arg), args, nil
|
||||
default:
|
||||
return reflect.Value{}, nil, fmt.Errorf("cannot convert %v to string", arg)
|
||||
}
|
||||
}, nil
|
||||
case pt.Kind() == reflect.String:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
switch arg := arg.(type) {
|
||||
case expect.Identifier:
|
||||
return reflect.ValueOf(string(arg)), args, nil
|
||||
case string:
|
||||
return reflect.ValueOf(arg), args, nil
|
||||
default:
|
||||
return reflect.Value{}, nil, fmt.Errorf("cannot convert %v to string", arg)
|
||||
}
|
||||
}, nil
|
||||
case pt.Kind() == reflect.Int64:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
switch arg := arg.(type) {
|
||||
case int64:
|
||||
return reflect.ValueOf(arg), args, nil
|
||||
default:
|
||||
return reflect.Value{}, nil, fmt.Errorf("cannot convert %v to int", arg)
|
||||
}
|
||||
}, nil
|
||||
case pt.Kind() == reflect.Bool:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
b, ok := arg.(bool)
|
||||
if !ok {
|
||||
return reflect.Value{}, nil, fmt.Errorf("cannot convert %v to bool", arg)
|
||||
}
|
||||
return reflect.ValueOf(b), args, nil
|
||||
}, nil
|
||||
case pt.Kind() == reflect.Slice:
|
||||
return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) {
|
||||
converter, err := e.buildConverter(pt.Elem())
|
||||
if err != nil {
|
||||
return reflect.Value{}, nil, err
|
||||
}
|
||||
result := reflect.MakeSlice(reflect.SliceOf(pt.Elem()), 0, len(args))
|
||||
for range args {
|
||||
value, remains, err := converter(n, args)
|
||||
if err != nil {
|
||||
return reflect.Value{}, nil, err
|
||||
}
|
||||
result = reflect.Append(result, value)
|
||||
args = remains
|
||||
}
|
||||
return result, args, nil
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("param has invalid type %v", pt)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Exported) rangeConverter(n *expect.Note, args []interface{}) (Range, []interface{}, error) {
|
||||
if len(args) < 1 {
|
||||
return Range{}, nil, fmt.Errorf("missing argument")
|
||||
}
|
||||
arg := args[0]
|
||||
args = args[1:]
|
||||
switch arg := arg.(type) {
|
||||
case expect.Identifier:
|
||||
// handle the special identifiers
|
||||
switch arg {
|
||||
case eofIdentifier:
|
||||
// end of file identifier, look up the current file
|
||||
f := e.fset.File(n.Pos)
|
||||
eof := f.Pos(f.Size())
|
||||
return Range{Start: eof, End: token.NoPos}, args, nil
|
||||
default:
|
||||
// look up an marker by name
|
||||
mark, ok := e.markers[string(arg)]
|
||||
if !ok {
|
||||
return Range{}, nil, fmt.Errorf("cannot find marker %v", arg)
|
||||
}
|
||||
return mark, args, nil
|
||||
}
|
||||
case string:
|
||||
start, end, err := expect.MatchBefore(e.fset, e.fileContents, n.Pos, arg)
|
||||
if err != nil {
|
||||
return Range{}, nil, err
|
||||
}
|
||||
if start == token.NoPos {
|
||||
return Range{}, nil, fmt.Errorf("%v: pattern %s did not match", e.fset.Position(n.Pos), arg)
|
||||
}
|
||||
return Range{Start: start, End: end}, args, nil
|
||||
case *regexp.Regexp:
|
||||
start, end, err := expect.MatchBefore(e.fset, e.fileContents, n.Pos, arg)
|
||||
if err != nil {
|
||||
return Range{}, nil, err
|
||||
}
|
||||
if start == token.NoPos {
|
||||
return Range{}, nil, fmt.Errorf("%v: pattern %s did not match", e.fset.Position(n.Pos), arg)
|
||||
}
|
||||
return Range{Start: start, End: end}, args, nil
|
||||
default:
|
||||
return Range{}, nil, fmt.Errorf("cannot convert %v to pos", arg)
|
||||
}
|
||||
}
|
66
vendor/golang.org/x/tools/go/packages/packagestest/expect_test.go
generated
vendored
Normal file
66
vendor/golang.org/x/tools/go/packages/packagestest/expect_test.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package packagestest_test
|
||||
|
||||
import (
|
||||
"go/token"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/expect"
|
||||
"golang.org/x/tools/go/packages/packagestest"
|
||||
)
|
||||
|
||||
func TestExpect(t *testing.T) {
|
||||
exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: packagestest.MustCopyFileTree("testdata"),
|
||||
}})
|
||||
defer exported.Cleanup()
|
||||
count := 0
|
||||
if err := exported.Expect(map[string]interface{}{
|
||||
"check": func(src, target token.Position) {
|
||||
count++
|
||||
},
|
||||
"boolArg": func(n *expect.Note, yes, no bool) {
|
||||
if !yes {
|
||||
t.Errorf("Expected boolArg first param to be true")
|
||||
}
|
||||
if no {
|
||||
t.Errorf("Expected boolArg second param to be false")
|
||||
}
|
||||
},
|
||||
"intArg": func(n *expect.Note, i int64) {
|
||||
if i != 42 {
|
||||
t.Errorf("Expected intarg to be 42")
|
||||
}
|
||||
},
|
||||
"stringArg": func(n *expect.Note, name expect.Identifier, value string) {
|
||||
if string(name) != value {
|
||||
t.Errorf("Got string arg %v expected %v", value, name)
|
||||
}
|
||||
},
|
||||
"directNote": func(n *expect.Note) {},
|
||||
"range": func(r packagestest.Range) {
|
||||
if r.Start == token.NoPos || r.Start == 0 {
|
||||
t.Errorf("Range had no valid starting position")
|
||||
}
|
||||
if r.End == token.NoPos || r.End == 0 {
|
||||
t.Errorf("Range had no valid ending position")
|
||||
} else if r.End <= r.Start {
|
||||
t.Errorf("Range ending was not greater than start")
|
||||
}
|
||||
},
|
||||
"checkEOF": func(n *expect.Note, p token.Pos) {
|
||||
if p <= n.Pos {
|
||||
t.Errorf("EOF was before the checkEOF note")
|
||||
}
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if count == 0 {
|
||||
t.Fatalf("No tests were run")
|
||||
}
|
||||
}
|
281
vendor/golang.org/x/tools/go/packages/packagestest/export.go
generated
vendored
Normal file
281
vendor/golang.org/x/tools/go/packages/packagestest/export.go
generated
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package packagestest creates temporary projects on disk for testing go tools on.
|
||||
|
||||
By changing the exporter used, you can create projects for multiple build
|
||||
systems from the same description, and run the same tests on them in many
|
||||
cases.
|
||||
*/
|
||||
package packagestest
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/expect"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
var (
|
||||
skipCleanup = flag.Bool("skip-cleanup", false, "Do not delete the temporary export folders") // for debugging
|
||||
)
|
||||
|
||||
// Module is a representation of a go module.
|
||||
type Module struct {
|
||||
// Name is the base name of the module as it would be in the go.mod file.
|
||||
Name string
|
||||
// Files is the set of source files for all packages that make up the module.
|
||||
// The keys are the file fragment that follows the module name, the value can
|
||||
// be a string or byte slice, in which case it is the contents of the
|
||||
// file, otherwise it must be a Writer function.
|
||||
Files map[string]interface{}
|
||||
}
|
||||
|
||||
// A Writer is a function that writes out a test file.
|
||||
// It is provided the name of the file to write, and may return an error if it
|
||||
// cannot write the file.
|
||||
// These are used as the content of the Files map in a Module.
|
||||
type Writer func(filename string) error
|
||||
|
||||
// Exported is returned by the Export function to report the structure that was produced on disk.
|
||||
type Exported struct {
|
||||
// Config is a correctly configured packages.Config ready to be passed to packages.Load.
|
||||
// Exactly what it will contain varies depending on the Exporter being used.
|
||||
Config *packages.Config
|
||||
|
||||
temp string // the temporary directory that was exported to
|
||||
primary string // the first non GOROOT module that was exported
|
||||
written map[string]map[string]string // the full set of exported files
|
||||
fset *token.FileSet // The file set used when parsing expectations
|
||||
notes []*expect.Note // The list of expectations extracted from go source files
|
||||
markers map[string]Range // The set of markers extracted from go source files
|
||||
contents map[string][]byte
|
||||
}
|
||||
|
||||
// Exporter implementations are responsible for converting from the generic description of some
|
||||
// test data to a driver specific file layout.
|
||||
type Exporter interface {
|
||||
// Name reports the name of the exporter, used in logging and sub-test generation.
|
||||
Name() string
|
||||
// Filename reports the system filename for test data source file.
|
||||
// It is given the base directory, the module the file is part of and the filename fragment to
|
||||
// work from.
|
||||
Filename(exported *Exported, module, fragment string) string
|
||||
// Finalize is called once all files have been written to write any extra data needed and modify
|
||||
// the Config to match. It is handed the full list of modules that were encountered while writing
|
||||
// files.
|
||||
Finalize(exported *Exported) error
|
||||
}
|
||||
|
||||
// All is the list of known exporters.
|
||||
// This is used by TestAll to run tests with all the exporters.
|
||||
var All []Exporter
|
||||
|
||||
// TestAll invokes the testing function once for each exporter registered in
|
||||
// the All global.
|
||||
// Each exporter will be run as a sub-test named after the exporter being used.
|
||||
func TestAll(t *testing.T, f func(*testing.T, Exporter)) {
|
||||
t.Helper()
|
||||
for _, e := range All {
|
||||
t.Run(e.Name(), func(t *testing.T) {
|
||||
t.Helper()
|
||||
f(t, e)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Export is called to write out a test directory from within a test function.
|
||||
// It takes the exporter and the build system agnostic module descriptions, and
|
||||
// uses them to build a temporary directory.
|
||||
// It returns an Exported with the results of the export.
|
||||
// The Exported.Config is prepared for loading from the exported data.
|
||||
// You must invoke Exported.Cleanup on the returned value to clean up.
|
||||
// The file deletion in the cleanup can be skipped by setting the skip-cleanup
|
||||
// flag when invoking the test, allowing the temporary directory to be left for
|
||||
// debugging tests.
|
||||
func Export(t *testing.T, exporter Exporter, modules []Module) *Exported {
|
||||
t.Helper()
|
||||
dirname := strings.Replace(t.Name(), "/", "_", -1)
|
||||
dirname = strings.Replace(dirname, "#", "_", -1) // duplicate subtests get a #NNN suffix.
|
||||
temp, err := ioutil.TempDir("", dirname)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
exported := &Exported{
|
||||
Config: &packages.Config{
|
||||
Dir: temp,
|
||||
Env: append(os.Environ(), "GOPACKAGESDRIVER=off"),
|
||||
},
|
||||
temp: temp,
|
||||
primary: modules[0].Name,
|
||||
written: map[string]map[string]string{},
|
||||
fset: token.NewFileSet(),
|
||||
contents: map[string][]byte{},
|
||||
}
|
||||
defer func() {
|
||||
if t.Failed() || t.Skipped() {
|
||||
exported.Cleanup()
|
||||
}
|
||||
}()
|
||||
for _, module := range modules {
|
||||
for fragment, value := range module.Files {
|
||||
fullpath := exporter.Filename(exported, module.Name, filepath.FromSlash(fragment))
|
||||
written, ok := exported.written[module.Name]
|
||||
if !ok {
|
||||
written = map[string]string{}
|
||||
exported.written[module.Name] = written
|
||||
}
|
||||
written[fragment] = fullpath
|
||||
if err := os.MkdirAll(filepath.Dir(fullpath), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch value := value.(type) {
|
||||
case Writer:
|
||||
if err := value(fullpath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
case string:
|
||||
if err := ioutil.WriteFile(fullpath, []byte(value), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("Invalid type %T in files, must be string or Writer", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := exporter.Finalize(exported); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return exported
|
||||
}
|
||||
|
||||
// Script returns a Writer that writes out contents to the file and sets the
|
||||
// executable bit on the created file.
|
||||
// It is intended for source files that are shell scripts.
|
||||
func Script(contents string) Writer {
|
||||
return func(filename string) error {
|
||||
return ioutil.WriteFile(filename, []byte(contents), 0755)
|
||||
}
|
||||
}
|
||||
|
||||
// Link returns a Writer that creates a hard link from the specified source to
|
||||
// the required file.
|
||||
// This is used to link testdata files into the generated testing tree.
|
||||
func Link(source string) Writer {
|
||||
return func(filename string) error {
|
||||
return os.Link(source, filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Symlink returns a Writer that creates a symlink from the specified source to the
|
||||
// required file.
|
||||
// This is used to link testdata files into the generated testing tree.
|
||||
func Symlink(source string) Writer {
|
||||
if !strings.HasPrefix(source, ".") {
|
||||
if abspath, err := filepath.Abs(source); err == nil {
|
||||
if _, err := os.Stat(source); !os.IsNotExist(err) {
|
||||
source = abspath
|
||||
}
|
||||
}
|
||||
}
|
||||
return func(filename string) error {
|
||||
return os.Symlink(source, filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Copy returns a Writer that copies a file from the specified source to the
|
||||
// required file.
|
||||
// This is used to copy testdata files into the generated testing tree.
|
||||
func Copy(source string) Writer {
|
||||
return func(filename string) error {
|
||||
stat, err := os.Stat(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !stat.Mode().IsRegular() {
|
||||
// cannot copy non-regular files (e.g., directories,
|
||||
// symlinks, devices, etc.)
|
||||
return fmt.Errorf("Cannot copy non regular file %s", source)
|
||||
}
|
||||
contents, err := ioutil.ReadFile(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(filename, contents, stat.Mode())
|
||||
}
|
||||
}
|
||||
|
||||
// MustCopyFileTree returns a file set for a module based on a real directory tree.
|
||||
// It scans the directory tree anchored at root and adds a Copy writer to the
|
||||
// map for every file found.
|
||||
// This is to enable the common case in tests where you have a full copy of the
|
||||
// package in your testdata.
|
||||
// This will panic if there is any kind of error trying to walk the file tree.
|
||||
func MustCopyFileTree(root string) map[string]interface{} {
|
||||
result := map[string]interface{}{}
|
||||
if err := filepath.Walk(filepath.FromSlash(root), func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
fragment, err := filepath.Rel(root, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result[fragment] = Copy(path)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Panic(fmt.Sprintf("MustCopyFileTree failed: %v", err))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Cleanup removes the temporary directory (unless the --skip-cleanup flag was set)
|
||||
// It is safe to call cleanup multiple times.
|
||||
func (e *Exported) Cleanup() {
|
||||
if e.temp == "" {
|
||||
return
|
||||
}
|
||||
if *skipCleanup {
|
||||
log.Printf("Skipping cleanup of temp dir: %s", e.temp)
|
||||
return
|
||||
}
|
||||
os.RemoveAll(e.temp) // ignore errors
|
||||
e.temp = ""
|
||||
}
|
||||
|
||||
// Temp returns the temporary directory that was generated.
|
||||
func (e *Exported) Temp() string {
|
||||
return e.temp
|
||||
}
|
||||
|
||||
// File returns the full path for the given module and file fragment.
|
||||
func (e *Exported) File(module, fragment string) string {
|
||||
if m := e.written[module]; m != nil {
|
||||
return m[fragment]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *Exported) fileContents(filename string) ([]byte, error) {
|
||||
if content, found := e.contents[filename]; found {
|
||||
return content, nil
|
||||
}
|
||||
content, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return content, nil
|
||||
}
|
73
vendor/golang.org/x/tools/go/packages/packagestest/export_test.go
generated
vendored
Normal file
73
vendor/golang.org/x/tools/go/packages/packagestest/export_test.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package packagestest_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/packages/packagestest"
|
||||
)
|
||||
|
||||
var testdata = []packagestest.Module{{
|
||||
Name: "golang.org/fake1",
|
||||
Files: map[string]interface{}{
|
||||
"a.go": packagestest.Symlink("testdata/a.go"),
|
||||
"b.go": "package fake1",
|
||||
},
|
||||
}, {
|
||||
Name: "golang.org/fake2",
|
||||
Files: map[string]interface{}{
|
||||
"other/a.go": "package fake2",
|
||||
},
|
||||
}, {
|
||||
Name: "golang.org/fake2/v2",
|
||||
Files: map[string]interface{}{
|
||||
"other/a.go": "package fake2",
|
||||
},
|
||||
}}
|
||||
|
||||
type fileTest struct {
|
||||
module, fragment, expect string
|
||||
check func(t *testing.T, filename string)
|
||||
}
|
||||
|
||||
func checkFiles(t *testing.T, exported *packagestest.Exported, tests []fileTest) {
|
||||
for _, test := range tests {
|
||||
expect := filepath.Join(exported.Temp(), filepath.FromSlash(test.expect))
|
||||
got := exported.File(test.module, test.fragment)
|
||||
if got == "" {
|
||||
t.Errorf("File %v missing from the output", expect)
|
||||
} else if got != expect {
|
||||
t.Errorf("Got file %v, expected %v", got, expect)
|
||||
}
|
||||
if test.check != nil {
|
||||
test.check(t, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkLink(expect string) func(t *testing.T, filename string) {
|
||||
expect = filepath.FromSlash(expect)
|
||||
return func(t *testing.T, filename string) {
|
||||
if target, err := os.Readlink(filename); err != nil {
|
||||
t.Errorf("Error checking link %v: %v", filename, err)
|
||||
} else if target != expect {
|
||||
t.Errorf("Link %v does not match, got %v expected %v", filename, target, expect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkContent(expect string) func(t *testing.T, filename string) {
|
||||
return func(t *testing.T, filename string) {
|
||||
if content, err := ioutil.ReadFile(filename); err != nil {
|
||||
t.Errorf("Error reading %v: %v", filename, err)
|
||||
} else if string(content) != expect {
|
||||
t.Errorf("Content of %v does not match, got %v expected %v", filename, string(content), expect)
|
||||
}
|
||||
}
|
||||
}
|
74
vendor/golang.org/x/tools/go/packages/packagestest/gopath.go
generated
vendored
Normal file
74
vendor/golang.org/x/tools/go/packages/packagestest/gopath.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package packagestest
|
||||
|
||||
import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// GOPATH is the exporter that produces GOPATH layouts.
|
||||
// Each "module" is put in it's own GOPATH entry to help test complex cases.
|
||||
// Given the two files
|
||||
// golang.org/repoa#a/a.go
|
||||
// golang.org/repob#b/b.go
|
||||
// You would get the directory layout
|
||||
// /sometemporarydirectory
|
||||
// ├── repoa
|
||||
// │ └── src
|
||||
// │ └── golang.org
|
||||
// │ └── repoa
|
||||
// │ └── a
|
||||
// │ └── a.go
|
||||
// └── repob
|
||||
// └── src
|
||||
// └── golang.org
|
||||
// └── repob
|
||||
// └── b
|
||||
// └── b.go
|
||||
// GOPATH would be set to
|
||||
// /sometemporarydirectory/repoa;/sometemporarydirectory/repob
|
||||
// and the working directory would be
|
||||
// /sometemporarydirectory/repoa/src
|
||||
var GOPATH = gopath{}
|
||||
|
||||
func init() {
|
||||
All = append(All, GOPATH)
|
||||
}
|
||||
|
||||
type gopath struct{}
|
||||
|
||||
func (gopath) Name() string {
|
||||
return "GOPATH"
|
||||
}
|
||||
|
||||
func (gopath) Filename(exported *Exported, module, fragment string) string {
|
||||
return filepath.Join(gopathDir(exported, module), "src", module, fragment)
|
||||
}
|
||||
|
||||
func (gopath) Finalize(exported *Exported) error {
|
||||
exported.Config.Env = append(exported.Config.Env, "GO111MODULE=off")
|
||||
gopath := ""
|
||||
for module := range exported.written {
|
||||
if gopath != "" {
|
||||
gopath += string(filepath.ListSeparator)
|
||||
}
|
||||
dir := gopathDir(exported, module)
|
||||
gopath += dir
|
||||
if module == exported.primary {
|
||||
exported.Config.Dir = filepath.Join(dir, "src")
|
||||
}
|
||||
}
|
||||
exported.Config.Env = append(exported.Config.Env, "GOPATH="+gopath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func gopathDir(exported *Exported, module string) string {
|
||||
dir := path.Base(module)
|
||||
if versionSuffixRE.MatchString(dir) {
|
||||
dir = path.Base(path.Dir(module)) + "_" + dir
|
||||
}
|
||||
return filepath.Join(exported.temp, dir)
|
||||
}
|
28
vendor/golang.org/x/tools/go/packages/packagestest/gopath_test.go
generated
vendored
Normal file
28
vendor/golang.org/x/tools/go/packages/packagestest/gopath_test.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package packagestest_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/packages/packagestest"
|
||||
)
|
||||
|
||||
func TestGOPATHExport(t *testing.T) {
|
||||
exported := packagestest.Export(t, packagestest.GOPATH, testdata)
|
||||
defer exported.Cleanup()
|
||||
// Check that the cfg contains all the right bits
|
||||
var expectDir = filepath.Join(exported.Temp(), "fake1", "src")
|
||||
if exported.Config.Dir != expectDir {
|
||||
t.Errorf("Got working directory %v expected %v", exported.Config.Dir, expectDir)
|
||||
}
|
||||
checkFiles(t, exported, []fileTest{
|
||||
{"golang.org/fake1", "a.go", "fake1/src/golang.org/fake1/a.go", checkLink("testdata/a.go")},
|
||||
{"golang.org/fake1", "b.go", "fake1/src/golang.org/fake1/b.go", checkContent("package fake1")},
|
||||
{"golang.org/fake2", "other/a.go", "fake2/src/golang.org/fake2/other/a.go", checkContent("package fake2")},
|
||||
{"golang.org/fake2/v2", "other/a.go", "fake2_v2/src/golang.org/fake2/v2/other/a.go", checkContent("package fake2")},
|
||||
})
|
||||
}
|
210
vendor/golang.org/x/tools/go/packages/packagestest/modules.go
generated
vendored
Normal file
210
vendor/golang.org/x/tools/go/packages/packagestest/modules.go
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package packagestest
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// Modules is the exporter that produces module layouts.
|
||||
// Each "repository" is put in it's own module, and the module file generated
|
||||
// will have replace directives for all other modules.
|
||||
// Given the two files
|
||||
// golang.org/repoa#a/a.go
|
||||
// golang.org/repob#b/b.go
|
||||
// You would get the directory layout
|
||||
// /sometemporarydirectory
|
||||
// ├── repoa
|
||||
// │ ├── a
|
||||
// │ │ └── a.go
|
||||
// │ └── go.mod
|
||||
// └── repob
|
||||
// ├── b
|
||||
// │ └── b.go
|
||||
// └── go.mod
|
||||
// and the working directory would be
|
||||
// /sometemporarydirectory/repoa
|
||||
var Modules = modules{}
|
||||
|
||||
type modules struct{}
|
||||
|
||||
func (modules) Name() string {
|
||||
return "Modules"
|
||||
}
|
||||
|
||||
func (modules) Filename(exported *Exported, module, fragment string) string {
|
||||
if module == exported.primary {
|
||||
return filepath.Join(primaryDir(exported), fragment)
|
||||
}
|
||||
return filepath.Join(moduleDir(exported, module), fragment)
|
||||
}
|
||||
|
||||
func (modules) Finalize(exported *Exported) error {
|
||||
// Write out the primary module. This module can use symlinks and
|
||||
// other weird stuff, and will be the working dir for the go command.
|
||||
// It depends on all the other modules.
|
||||
primaryDir := primaryDir(exported)
|
||||
exported.Config.Dir = primaryDir
|
||||
exported.written[exported.primary]["go.mod"] = filepath.Join(primaryDir, "go.mod")
|
||||
primaryGomod := "module " + exported.primary + "\nrequire (\n"
|
||||
for other := range exported.written {
|
||||
if other == exported.primary {
|
||||
continue
|
||||
}
|
||||
primaryGomod += fmt.Sprintf("\t%v %v\n", other, moduleVersion(other))
|
||||
}
|
||||
primaryGomod += ")\n"
|
||||
if err := ioutil.WriteFile(filepath.Join(primaryDir, "go.mod"), []byte(primaryGomod), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the mod cache so we can rename it later, even if we don't need it.
|
||||
if err := os.MkdirAll(modCache(exported), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write out the go.mod files for the other modules.
|
||||
for module, files := range exported.written {
|
||||
if module == exported.primary {
|
||||
continue
|
||||
}
|
||||
dir := moduleDir(exported, module)
|
||||
|
||||
modfile := filepath.Join(dir, "go.mod")
|
||||
if err := ioutil.WriteFile(modfile, []byte("module "+module+"\n"), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
files["go.mod"] = modfile
|
||||
}
|
||||
|
||||
// Zip up all the secondary modules into the proxy dir.
|
||||
proxyDir := filepath.Join(exported.temp, "modproxy")
|
||||
for module, files := range exported.written {
|
||||
if module == exported.primary {
|
||||
continue
|
||||
}
|
||||
dir := filepath.Join(proxyDir, module, "@v")
|
||||
|
||||
if err := writeModuleProxy(dir, module, files); err != nil {
|
||||
return fmt.Errorf("creating module proxy dir for %v: %v", module, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Discard the original mod cache dir, which contained the files written
|
||||
// for us by Export.
|
||||
if err := os.Rename(modCache(exported), modCache(exported)+".orig"); err != nil {
|
||||
return err
|
||||
}
|
||||
exported.Config.Env = append(exported.Config.Env,
|
||||
"GO111MODULE=on",
|
||||
"GOPATH="+filepath.Join(exported.temp, "modcache"),
|
||||
"GOPROXY=file://"+filepath.ToSlash(proxyDir))
|
||||
|
||||
// Run go mod download to recreate the mod cache dir with all the extra
|
||||
// stuff in cache. All the files created by Export should be recreated.
|
||||
if err := invokeGo(exported.Config, "mod", "download"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeModuleProxy creates a directory in the proxy dir for a module.
|
||||
func writeModuleProxy(dir, module string, files map[string]string) error {
|
||||
ver := moduleVersion(module)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// list file. Just the single version.
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "list"), []byte(ver+"\n"), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// go.mod, copied from the file written in Finalize.
|
||||
modContents, err := ioutil.ReadFile(files["go.mod"])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, ver+".mod"), modContents, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// info file, just the bare bones.
|
||||
infoContents := []byte(fmt.Sprintf(`{"Version": "%v", "Time":"2017-12-14T13:08:43Z"}`, ver))
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, ver+".info"), infoContents, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// zip of all the source files.
|
||||
f, err := os.OpenFile(filepath.Join(dir, ver+".zip"), os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
z := zip.NewWriter(f)
|
||||
for name, path := range files {
|
||||
zf, err := z.Create(module + "@" + ver + "/" + name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contents, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := zf.Write(contents); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := z.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func invokeGo(cfg *packages.Config, args ...string) error {
|
||||
stdout := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
cmd := exec.Command("go", args...)
|
||||
cmd.Env = append(append([]string{}, cfg.Env...), "PWD="+cfg.Dir)
|
||||
cmd.Dir = cfg.Dir
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("go %v: %s: %s", args, err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func modCache(exported *Exported) string {
|
||||
return filepath.Join(exported.temp, "modcache/pkg/mod")
|
||||
}
|
||||
|
||||
func primaryDir(exported *Exported) string {
|
||||
return filepath.Join(exported.temp, "primarymod", path.Base(exported.primary))
|
||||
}
|
||||
|
||||
func moduleDir(exported *Exported, module string) string {
|
||||
return filepath.Join(modCache(exported), path.Dir(module), path.Base(module)+"@"+moduleVersion(module))
|
||||
}
|
||||
|
||||
var versionSuffixRE = regexp.MustCompile(`v\d+`)
|
||||
|
||||
func moduleVersion(module string) string {
|
||||
if versionSuffixRE.MatchString(path.Base(module)) {
|
||||
return path.Base(module) + ".0.0"
|
||||
}
|
||||
return "v1.0.0"
|
||||
}
|
7
vendor/golang.org/x/tools/go/packages/packagestest/modules_111.go
generated
vendored
Normal file
7
vendor/golang.org/x/tools/go/packages/packagestest/modules_111.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// +build go1.11
|
||||
|
||||
package packagestest
|
||||
|
||||
func init() {
|
||||
All = append(All, Modules)
|
||||
}
|
32
vendor/golang.org/x/tools/go/packages/packagestest/modules_test.go
generated
vendored
Normal file
32
vendor/golang.org/x/tools/go/packages/packagestest/modules_test.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.11
|
||||
|
||||
package packagestest_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/packages/packagestest"
|
||||
)
|
||||
|
||||
func TestModulesExport(t *testing.T) {
|
||||
exported := packagestest.Export(t, packagestest.Modules, testdata)
|
||||
defer exported.Cleanup()
|
||||
// Check that the cfg contains all the right bits
|
||||
var expectDir = filepath.Join(exported.Temp(), "primarymod/fake1")
|
||||
if exported.Config.Dir != expectDir {
|
||||
t.Errorf("Got working directory %v expected %v", exported.Config.Dir, expectDir)
|
||||
}
|
||||
checkFiles(t, exported, []fileTest{
|
||||
{"golang.org/fake1", "go.mod", "primarymod/fake1/go.mod", nil},
|
||||
{"golang.org/fake1", "a.go", "primarymod/fake1/a.go", checkLink("testdata/a.go")},
|
||||
{"golang.org/fake1", "b.go", "primarymod/fake1/b.go", checkContent("package fake1")},
|
||||
{"golang.org/fake2", "go.mod", "modcache/pkg/mod/golang.org/fake2@v1.0.0/go.mod", nil},
|
||||
{"golang.org/fake2", "other/a.go", "modcache/pkg/mod/golang.org/fake2@v1.0.0/other/a.go", checkContent("package fake2")},
|
||||
{"golang.org/fake2/v2", "other/a.go", "modcache/pkg/mod/golang.org/fake2/v2@v2.0.0/other/a.go", checkContent("package fake2")},
|
||||
})
|
||||
}
|
24
vendor/golang.org/x/tools/go/packages/packagestest/testdata/test.go
generated
vendored
Normal file
24
vendor/golang.org/x/tools/go/packages/packagestest/testdata/test.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fake1
|
||||
|
||||
// This is a test file for the behaviors in Exported.Expect.
|
||||
|
||||
type AThing string //@AThing,mark(StringThing, "AThing"),mark(REThing,re`.T.*g`)
|
||||
|
||||
type Match string //@check("Match",re`[[:upper:]]`)
|
||||
|
||||
//@check(AThing, StringThing)
|
||||
//@check(AThing, REThing)
|
||||
|
||||
//@boolArg(true, false)
|
||||
//@intArg(42)
|
||||
//@stringArg(PlainString, "PlainString")
|
||||
//@stringArg(IdentAsString,IdentAsString)
|
||||
//@directNote()
|
||||
//@range(AThing)
|
||||
|
||||
// The following test should remain at the bottom of the file
|
||||
//@checkEOF(EOF)
|
Reference in New Issue
Block a user