mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Make go2idl handle vendor dirs
This commit is contained in:
parent
492aad6de3
commit
92567e1b06
@ -43,6 +43,8 @@ type Builder struct {
|
|||||||
fset *token.FileSet
|
fset *token.FileSet
|
||||||
// map of package id to list of parsed files
|
// map of package id to list of parsed files
|
||||||
parsed map[string][]parsedFile
|
parsed map[string][]parsedFile
|
||||||
|
// map of package id to absolute path (to prevent overlap)
|
||||||
|
absPaths map[string]string
|
||||||
|
|
||||||
// Set by makePackages, used by importer() and friends.
|
// Set by makePackages, used by importer() and friends.
|
||||||
pkgs map[string]*tc.Package
|
pkgs map[string]*tc.Package
|
||||||
@ -81,11 +83,15 @@ func New() *Builder {
|
|||||||
fmt.Printf("Warning: $GOROOT not set, and unable to run `which go` to find it: %v\n", err)
|
fmt.Printf("Warning: $GOROOT not set, and unable to run `which go` to find it: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Force this to off, since we don't properly parse CGo. All symbols must
|
||||||
|
// have non-CGo equivalents.
|
||||||
|
c.CgoEnabled = false
|
||||||
return &Builder{
|
return &Builder{
|
||||||
context: &c,
|
context: &c,
|
||||||
buildInfo: map[string]*build.Package{},
|
buildInfo: map[string]*build.Package{},
|
||||||
fset: token.NewFileSet(),
|
fset: token.NewFileSet(),
|
||||||
parsed: map[string][]parsedFile{},
|
parsed: map[string][]parsedFile{},
|
||||||
|
absPaths: map[string]string{},
|
||||||
userRequested: map[string]bool{},
|
userRequested: map[string]bool{},
|
||||||
endLineToCommentGroup: map[fileLine]*ast.CommentGroup{},
|
endLineToCommentGroup: map[fileLine]*ast.CommentGroup{},
|
||||||
importGraph: map[string]map[string]struct{}{},
|
importGraph: map[string]map[string]struct{}{},
|
||||||
@ -101,8 +107,18 @@ func (b *Builder) AddBuildTags(tags ...string) {
|
|||||||
// e.g. test files and files for other platforms-- there is quite a bit of
|
// e.g. test files and files for other platforms-- there is quite a bit of
|
||||||
// logic of that nature in the build package.
|
// logic of that nature in the build package.
|
||||||
func (b *Builder) buildPackage(pkgPath string) (*build.Package, error) {
|
func (b *Builder) buildPackage(pkgPath string) (*build.Package, error) {
|
||||||
|
// This is a bit of a hack. The srcDir argument to Import() should
|
||||||
|
// properly be the dir of the file which depends on the package to be
|
||||||
|
// imported, so that vendoring can work properly. We assume that there is
|
||||||
|
// only one level of vendoring, and that the CWD is inside the GOPATH, so
|
||||||
|
// this should be safe.
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get current directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// First, find it, so we know what path to use.
|
// First, find it, so we know what path to use.
|
||||||
pkg, err := b.context.Import(pkgPath, ".", build.FindOnly)
|
pkg, err := b.context.Import(pkgPath, cwd, build.FindOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to *find* %q: %v", pkgPath, err)
|
return nil, fmt.Errorf("unable to *find* %q: %v", pkgPath, err)
|
||||||
}
|
}
|
||||||
@ -112,7 +128,7 @@ func (b *Builder) buildPackage(pkgPath string) (*build.Package, error) {
|
|||||||
if pkg, ok := b.buildInfo[pkgPath]; ok {
|
if pkg, ok := b.buildInfo[pkgPath]; ok {
|
||||||
return pkg, nil
|
return pkg, nil
|
||||||
}
|
}
|
||||||
pkg, err = b.context.Import(pkgPath, ".", build.ImportComment)
|
pkg, err = b.context.Import(pkgPath, cwd, build.ImportComment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to import %q: %v", pkgPath, err)
|
return nil, fmt.Errorf("unable to import %q: %v", pkgPath, err)
|
||||||
}
|
}
|
||||||
@ -127,21 +143,30 @@ func (b *Builder) buildPackage(pkgPath string) (*build.Package, error) {
|
|||||||
return pkg, nil
|
return pkg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddFile adds a file to the set. The name must be of the form canonical/pkg/path/file.go.
|
// AddFile adds a file to the set. The pkg must be of the form
|
||||||
func (b *Builder) AddFile(name string, src []byte) error {
|
// "canonical/pkg/path" and the path must be the absolute path to the file.
|
||||||
return b.addFile(name, src, true)
|
func (b *Builder) AddFile(pkg string, path string, src []byte) error {
|
||||||
|
return b.addFile(pkg, path, src, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addFile adds a file to the set. The name must be of the form
|
// addFile adds a file to the set. The pkg must be of the form
|
||||||
// canonical/pkg/path/file.go. A flag indicates whether this file was
|
// "canonical/pkg/path" and the path must be the absolute path to the file. A
|
||||||
// user-requested or just from following the import graph.
|
// flag indicates whether this file was user-requested or just from following
|
||||||
func (b *Builder) addFile(name string, src []byte, userRequested bool) error {
|
// the import graph.
|
||||||
p, err := parser.ParseFile(b.fset, name, src, parser.DeclarationErrors|parser.ParseComments)
|
func (b *Builder) addFile(pkg string, path string, src []byte, userRequested bool) error {
|
||||||
|
p, err := parser.ParseFile(b.fset, path, src, parser.DeclarationErrors|parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pkg := filepath.Dir(name)
|
dirPath := filepath.Dir(path)
|
||||||
b.parsed[pkg] = append(b.parsed[pkg], parsedFile{name, p})
|
if prev, found := b.absPaths[pkg]; found {
|
||||||
|
if dirPath != prev {
|
||||||
|
return fmt.Errorf("package %q (%s) previously resolved to %s", pkg, dirPath, prev)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b.absPaths[pkg] = dirPath
|
||||||
|
}
|
||||||
|
b.parsed[pkg] = append(b.parsed[pkg], parsedFile{path, p})
|
||||||
b.userRequested[pkg] = userRequested
|
b.userRequested[pkg] = userRequested
|
||||||
for _, c := range p.Comments {
|
for _, c := range p.Comments {
|
||||||
position := b.fset.Position(c.End())
|
position := b.fset.Position(c.End())
|
||||||
@ -171,8 +196,18 @@ func (b *Builder) AddDir(dir string) error {
|
|||||||
// subdirectories; it returns an error only if the path couldn't be resolved;
|
// subdirectories; it returns an error only if the path couldn't be resolved;
|
||||||
// any directories recursed into without go source are ignored.
|
// any directories recursed into without go source are ignored.
|
||||||
func (b *Builder) AddDirRecursive(dir string) error {
|
func (b *Builder) AddDirRecursive(dir string) error {
|
||||||
|
// This is a bit of a hack. The srcDir argument to Import() should
|
||||||
|
// properly be the dir of the file which depends on the package to be
|
||||||
|
// imported, so that vendoring can work properly. We assume that there is
|
||||||
|
// only one level of vendoring, and that the CWD is inside the GOPATH, so
|
||||||
|
// this should be safe.
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get current directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// First, find it, so we know what path to use.
|
// First, find it, so we know what path to use.
|
||||||
pkg, err := b.context.Import(dir, ".", build.FindOnly)
|
pkg, err := b.context.Import(dir, cwd, build.FindOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to *find* %q: %v", dir, err)
|
return fmt.Errorf("unable to *find* %q: %v", dir, err)
|
||||||
}
|
}
|
||||||
@ -203,7 +238,6 @@ func (b *Builder) addDir(dir string, userRequested bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dir = pkg.Dir
|
|
||||||
// Check in case this package was added (maybe dir was not canonical)
|
// Check in case this package was added (maybe dir was not canonical)
|
||||||
if _, alreadyAdded := b.parsed[dir]; alreadyAdded {
|
if _, alreadyAdded := b.parsed[dir]; alreadyAdded {
|
||||||
return nil
|
return nil
|
||||||
@ -214,14 +248,13 @@ func (b *Builder) addDir(dir string, userRequested bool) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
absPath := filepath.Join(pkg.Dir, n)
|
absPath := filepath.Join(pkg.Dir, n)
|
||||||
pkgPath := filepath.Join(pkg.ImportPath, n)
|
|
||||||
data, err := ioutil.ReadFile(absPath)
|
data, err := ioutil.ReadFile(absPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("while loading %q: %v", absPath, err)
|
return fmt.Errorf("while loading %q: %v", absPath, err)
|
||||||
}
|
}
|
||||||
err = b.addFile(pkgPath, data, userRequested)
|
err = b.addFile(dir, absPath, data, userRequested)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("while parsing %q: %v", pkgPath, err)
|
return fmt.Errorf("while parsing %q: %v", absPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -18,6 +18,7 @@ package parser_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"text/template"
|
"text/template"
|
||||||
@ -30,7 +31,7 @@ import (
|
|||||||
func construct(t *testing.T, files map[string]string, testNamer namer.Namer) (*parser.Builder, types.Universe, []*types.Type) {
|
func construct(t *testing.T, files map[string]string, testNamer namer.Namer) (*parser.Builder, types.Universe, []*types.Type) {
|
||||||
b := parser.New()
|
b := parser.New()
|
||||||
for name, src := range files {
|
for name, src := range files {
|
||||||
if err := b.AddFile(name, []byte(src)); err != nil {
|
if err := b.AddFile(filepath.Dir(name), name, []byte(src)); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user