mirror of
https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent.git
synced 2026-04-23 16:58:56 +02:00
Initial v1.0.0 commit
This commit is contained in:
52
vendor/github.com/gobuffalo/packr/v2/jam/parser/args.go
generated
vendored
Normal file
52
vendor/github.com/gobuffalo/packr/v2/jam/parser/args.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FromArgs is useful when writing packr store-cmd binaries.
|
||||
/*
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/gobuffalo/packr/v2/jam/parser"
|
||||
"github.com/markbates/s3packr/s3packr"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := parser.FromArgs(os.Args[1:], func(boxes parser.Boxes) error {
|
||||
for _, box := range boxes {
|
||||
s3 := s3packr.New(box)
|
||||
if err := s3.Pack(box); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
func FromArgs(args []string, fn func(Boxes) error) error {
|
||||
if len(args) == 0 {
|
||||
return fmt.Errorf("you must supply a payload")
|
||||
}
|
||||
payload := args[0]
|
||||
if len(payload) == 0 {
|
||||
return fmt.Errorf("you must supply a payload")
|
||||
}
|
||||
|
||||
var boxes Boxes
|
||||
err := json.Unmarshal([]byte(payload), &boxes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fn(boxes)
|
||||
}
|
||||
40
vendor/github.com/gobuffalo/packr/v2/jam/parser/box.go
generated
vendored
Normal file
40
vendor/github.com/gobuffalo/packr/v2/jam/parser/box.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Box found while parsing a file
|
||||
type Box struct {
|
||||
Name string // name of the box
|
||||
Path string // relative path of folder NewBox("./templates")
|
||||
AbsPath string // absolute path of Path
|
||||
Package string // the package name the box was found in
|
||||
PWD string // the PWD when the parser was run
|
||||
PackageDir string // the absolute path of the package where the box was found
|
||||
}
|
||||
|
||||
type Boxes []*Box
|
||||
|
||||
// String - json returned
|
||||
func (b Box) String() string {
|
||||
x, _ := json.Marshal(b)
|
||||
return string(x)
|
||||
}
|
||||
|
||||
// NewBox stub from the name and the path provided
|
||||
func NewBox(name string, path string) *Box {
|
||||
if len(name) == 0 {
|
||||
name = path
|
||||
}
|
||||
name = strings.Replace(name, "\"", "", -1)
|
||||
pwd, _ := os.Getwd()
|
||||
box := &Box{
|
||||
Name: name,
|
||||
Path: path,
|
||||
PWD: pwd,
|
||||
}
|
||||
return box
|
||||
}
|
||||
54
vendor/github.com/gobuffalo/packr/v2/jam/parser/file.go
generated
vendored
Normal file
54
vendor/github.com/gobuffalo/packr/v2/jam/parser/file.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// File that is to be parsed
|
||||
type File struct {
|
||||
io.Reader
|
||||
Path string
|
||||
AbsPath string
|
||||
}
|
||||
|
||||
// Name of the file "app.go"
|
||||
func (f File) Name() string {
|
||||
return f.Path
|
||||
}
|
||||
|
||||
// String returns the contents of the reader
|
||||
func (f *File) String() string {
|
||||
src, _ := ioutil.ReadAll(f)
|
||||
f.Reader = bytes.NewReader(src)
|
||||
return string(src)
|
||||
}
|
||||
|
||||
func (s *File) Write(p []byte) (int, error) {
|
||||
bb := &bytes.Buffer{}
|
||||
i, err := bb.Write(p)
|
||||
s.Reader = bb
|
||||
return i, err
|
||||
}
|
||||
|
||||
// NewFile takes the name of the file you want to
|
||||
// write to and a reader to reader from
|
||||
func NewFile(path string, r io.Reader) *File {
|
||||
if r == nil {
|
||||
r = &bytes.Buffer{}
|
||||
}
|
||||
if seek, ok := r.(io.Seeker); ok {
|
||||
seek.Seek(0, 0)
|
||||
}
|
||||
abs := path
|
||||
if !filepath.IsAbs(path) {
|
||||
abs, _ = filepath.Abs(path)
|
||||
}
|
||||
return &File{
|
||||
Reader: r,
|
||||
Path: path,
|
||||
AbsPath: abs,
|
||||
}
|
||||
}
|
||||
112
vendor/github.com/gobuffalo/packr/v2/jam/parser/finder.go
generated
vendored
Normal file
112
vendor/github.com/gobuffalo/packr/v2/jam/parser/finder.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gobuffalo/packr/v2/plog"
|
||||
"github.com/karrick/godirwalk"
|
||||
"github.com/markbates/errx"
|
||||
"github.com/markbates/oncer"
|
||||
)
|
||||
|
||||
type finder struct {
|
||||
id time.Time
|
||||
}
|
||||
|
||||
func (fd *finder) key(m, dir string) string {
|
||||
return fmt.Sprintf("%s-*parser.finder#%s-%s", fd.id, m, dir)
|
||||
}
|
||||
|
||||
// findAllGoFiles *.go files for a given diretory
|
||||
func (fd *finder) findAllGoFiles(dir string) ([]string, error) {
|
||||
var err error
|
||||
var names []string
|
||||
oncer.Do(fd.key("findAllGoFiles", dir), func() {
|
||||
plog.Debug(fd, "findAllGoFiles", "dir", dir)
|
||||
|
||||
callback := func(path string, do *godirwalk.Dirent) error {
|
||||
ext := filepath.Ext(path)
|
||||
if ext != ".go" {
|
||||
return nil
|
||||
}
|
||||
//check if path is a dir
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
names = append(names, path)
|
||||
return nil
|
||||
}
|
||||
err = godirwalk.Walk(dir, &godirwalk.Options{
|
||||
FollowSymbolicLinks: true,
|
||||
Callback: callback,
|
||||
})
|
||||
})
|
||||
|
||||
return names, err
|
||||
}
|
||||
|
||||
func (fd *finder) findAllGoFilesImports(dir string) ([]string, error) {
|
||||
var err error
|
||||
var names []string
|
||||
oncer.Do(fd.key("findAllGoFilesImports", dir), func() {
|
||||
ctx := build.Default
|
||||
|
||||
if len(ctx.SrcDirs()) == 0 {
|
||||
err = fmt.Errorf("no src directories found")
|
||||
return
|
||||
}
|
||||
|
||||
pkg, err := ctx.ImportDir(dir, 0)
|
||||
if strings.HasPrefix(pkg.ImportPath, "github.com/gobuffalo/packr") {
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "cannot find package") {
|
||||
if _, ok := errx.Unwrap(err).(*build.NoGoError); !ok {
|
||||
err = err
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pkg.Goroot {
|
||||
return
|
||||
}
|
||||
if len(pkg.GoFiles) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
plog.Debug(fd, "findAllGoFilesImports", "dir", dir)
|
||||
|
||||
names, _ = fd.findAllGoFiles(dir)
|
||||
for _, n := range pkg.GoFiles {
|
||||
names = append(names, filepath.Join(pkg.Dir, n))
|
||||
}
|
||||
for _, imp := range pkg.Imports {
|
||||
if len(ctx.SrcDirs()) == 0 {
|
||||
continue
|
||||
}
|
||||
d := ctx.SrcDirs()[len(ctx.SrcDirs())-1]
|
||||
ip := filepath.Join(d, imp)
|
||||
n, err := fd.findAllGoFilesImports(ip)
|
||||
if err != nil && len(n) != 0 {
|
||||
names = n
|
||||
return
|
||||
}
|
||||
names = append(names, n...)
|
||||
}
|
||||
})
|
||||
return names, err
|
||||
}
|
||||
43
vendor/github.com/gobuffalo/packr/v2/jam/parser/gogen.go
generated
vendored
Normal file
43
vendor/github.com/gobuffalo/packr/v2/jam/parser/gogen.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/packd"
|
||||
"github.com/markbates/errx"
|
||||
)
|
||||
|
||||
// ParsedFile ...
|
||||
type ParsedFile struct {
|
||||
File packd.SimpleFile
|
||||
FileSet *token.FileSet
|
||||
Ast *ast.File
|
||||
Lines []string
|
||||
}
|
||||
|
||||
// ParseFileMode ...
|
||||
func ParseFileMode(gf packd.SimpleFile, mode parser.Mode) (ParsedFile, error) {
|
||||
pf := ParsedFile{
|
||||
FileSet: token.NewFileSet(),
|
||||
File: gf,
|
||||
}
|
||||
|
||||
src := gf.String()
|
||||
f, err := parser.ParseFile(pf.FileSet, gf.Name(), src, mode)
|
||||
if err != nil && errx.Unwrap(err) != io.EOF {
|
||||
return pf, err
|
||||
}
|
||||
pf.Ast = f
|
||||
|
||||
pf.Lines = strings.Split(src, "\n")
|
||||
return pf, nil
|
||||
}
|
||||
|
||||
// ParseFile ...
|
||||
func ParseFile(gf packd.SimpleFile) (ParsedFile, error) {
|
||||
return ParseFileMode(gf, 0)
|
||||
}
|
||||
46
vendor/github.com/gobuffalo/packr/v2/jam/parser/parser.go
generated
vendored
Normal file
46
vendor/github.com/gobuffalo/packr/v2/jam/parser/parser.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/packr/v2/plog"
|
||||
)
|
||||
|
||||
// Parser to find boxes
|
||||
type Parser struct {
|
||||
Prospects []*File // a list of files to check for boxes
|
||||
IgnoreImports bool
|
||||
}
|
||||
|
||||
// Run the parser and run any boxes found
|
||||
func (p *Parser) Run() (Boxes, error) {
|
||||
var boxes Boxes
|
||||
for _, pros := range p.Prospects {
|
||||
plog.Debug(p, "Run", "parsing", pros.Name())
|
||||
v := NewVisitor(pros)
|
||||
pbr, err := v.Run()
|
||||
if err != nil {
|
||||
return boxes, err
|
||||
}
|
||||
for _, b := range pbr {
|
||||
plog.Debug(p, "Run", "file", pros.Name(), "box", b.Name)
|
||||
boxes = append(boxes, b)
|
||||
}
|
||||
}
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
sort.Slice(boxes, func(a, b int) bool {
|
||||
b1 := boxes[a]
|
||||
return !strings.HasPrefix(b1.AbsPath, pwd)
|
||||
})
|
||||
return boxes, nil
|
||||
}
|
||||
|
||||
// New Parser from a list of File
|
||||
func New(prospects ...*File) *Parser {
|
||||
return &Parser{
|
||||
Prospects: prospects,
|
||||
}
|
||||
}
|
||||
77
vendor/github.com/gobuffalo/packr/v2/jam/parser/prospect.go
generated
vendored
Normal file
77
vendor/github.com/gobuffalo/packr/v2/jam/parser/prospect.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
||||
"github.com/gobuffalo/packr/v2/plog"
|
||||
)
|
||||
|
||||
var DefaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "_fixtures", "testdata"}
|
||||
|
||||
func IsProspect(path string, ignore ...string) (status bool) {
|
||||
// plog.Debug("parser", "IsProspect", "path", path, "ignore", ignore)
|
||||
defer func() {
|
||||
if status {
|
||||
plog.Debug("parser", "IsProspect (TRUE)", "path", path, "status", status)
|
||||
}
|
||||
}()
|
||||
if path == "." {
|
||||
return true
|
||||
}
|
||||
|
||||
ext := filepath.Ext(path)
|
||||
dir := filepath.Dir(path)
|
||||
|
||||
fi, _ := os.Stat(path)
|
||||
if fi != nil {
|
||||
if fi.IsDir() {
|
||||
dir = filepath.Base(path)
|
||||
} else {
|
||||
if len(ext) > 0 {
|
||||
dir = filepath.Base(filepath.Dir(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path = strings.ToLower(path)
|
||||
dir = strings.ToLower(dir)
|
||||
|
||||
if strings.HasSuffix(path, "-packr.go") {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.HasSuffix(path, "_test.go") {
|
||||
return false
|
||||
}
|
||||
|
||||
ignore = append(ignore, DefaultIgnoredFolders...)
|
||||
for i, x := range ignore {
|
||||
ignore[i] = strings.TrimSpace(strings.ToLower(x))
|
||||
}
|
||||
|
||||
parts := strings.Split(resolver.OsPath(path), string(filepath.Separator))
|
||||
if len(parts) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, i := range ignore {
|
||||
for _, p := range parts {
|
||||
if strings.HasPrefix(p, i) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
un := filepath.Base(path)
|
||||
if len(ext) != 0 {
|
||||
un = filepath.Base(filepath.Dir(path))
|
||||
}
|
||||
if strings.HasPrefix(un, "_") {
|
||||
return false
|
||||
}
|
||||
|
||||
return ext == ".go"
|
||||
}
|
||||
89
vendor/github.com/gobuffalo/packr/v2/jam/parser/roots.go
generated
vendored
Normal file
89
vendor/github.com/gobuffalo/packr/v2/jam/parser/roots.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/gobuffalo/packr/v2/plog"
|
||||
"github.com/karrick/godirwalk"
|
||||
)
|
||||
|
||||
type RootsOptions struct {
|
||||
IgnoreImports bool
|
||||
Ignores []string
|
||||
}
|
||||
|
||||
func (r RootsOptions) String() string {
|
||||
x, _ := json.Marshal(r)
|
||||
return string(x)
|
||||
}
|
||||
|
||||
// NewFromRoots scans the file roots provided and returns a
|
||||
// new Parser containing the prospects
|
||||
func NewFromRoots(roots []string, opts *RootsOptions) (*Parser, error) {
|
||||
if opts == nil {
|
||||
opts = &RootsOptions{}
|
||||
}
|
||||
|
||||
if len(roots) == 0 {
|
||||
pwd, _ := os.Getwd()
|
||||
roots = append(roots, pwd)
|
||||
}
|
||||
p := New()
|
||||
plog.Debug(p, "NewFromRoots", "roots", roots, "options", opts)
|
||||
callback := func(path string, de *godirwalk.Dirent) error {
|
||||
if IsProspect(path, opts.Ignores...) {
|
||||
if de.IsDir() {
|
||||
return nil
|
||||
}
|
||||
roots = append(roots, path)
|
||||
return nil
|
||||
}
|
||||
if de.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
wopts := &godirwalk.Options{
|
||||
FollowSymbolicLinks: true,
|
||||
Callback: callback,
|
||||
}
|
||||
for _, root := range roots {
|
||||
plog.Debug(p, "NewFromRoots", "walking", root)
|
||||
err := godirwalk.Walk(root, wopts)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
}
|
||||
|
||||
dd := map[string]string{}
|
||||
fd := &finder{id: time.Now()}
|
||||
for _, r := range roots {
|
||||
var names []string
|
||||
if opts.IgnoreImports {
|
||||
names, _ = fd.findAllGoFiles(r)
|
||||
} else {
|
||||
names, _ = fd.findAllGoFilesImports(r)
|
||||
}
|
||||
for _, n := range names {
|
||||
if IsProspect(n) {
|
||||
plog.Debug(p, "NewFromRoots", "mapping", n)
|
||||
dd[n] = n
|
||||
}
|
||||
}
|
||||
}
|
||||
for path := range dd {
|
||||
plog.Debug(p, "NewFromRoots", "reading file", path)
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.Prospects = append(p.Prospects, NewFile(path, bytes.NewReader(b)))
|
||||
}
|
||||
plog.Debug(p, "NewFromRoots", "found prospects", len(p.Prospects))
|
||||
return p, nil
|
||||
}
|
||||
324
vendor/github.com/gobuffalo/packr/v2/jam/parser/visitor.go
generated
vendored
Normal file
324
vendor/github.com/gobuffalo/packr/v2/jam/parser/visitor.go
generated
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/packd"
|
||||
)
|
||||
|
||||
type Visitor struct {
|
||||
File packd.SimpleFile
|
||||
Package string
|
||||
boxes map[string]*Box
|
||||
errors []error
|
||||
}
|
||||
|
||||
func NewVisitor(f *File) *Visitor {
|
||||
return &Visitor{
|
||||
File: f,
|
||||
boxes: map[string]*Box{},
|
||||
errors: []error{},
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Visitor) Run() (Boxes, error) {
|
||||
var boxes Boxes
|
||||
pf, err := ParseFile(v.File)
|
||||
if err != nil {
|
||||
return boxes, err
|
||||
}
|
||||
|
||||
v.Package = pf.Ast.Name.Name
|
||||
ast.Walk(v, pf.Ast)
|
||||
|
||||
for _, vb := range v.boxes {
|
||||
boxes = append(boxes, vb)
|
||||
}
|
||||
|
||||
sort.Slice(boxes, func(i, j int) bool {
|
||||
return boxes[i].Name < boxes[j].Name
|
||||
})
|
||||
|
||||
if len(v.errors) > 0 {
|
||||
s := make([]string, len(v.errors))
|
||||
for i, e := range v.errors {
|
||||
s[i] = e.Error()
|
||||
}
|
||||
return boxes, err
|
||||
}
|
||||
return boxes, nil
|
||||
}
|
||||
|
||||
func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
if node == nil {
|
||||
return v
|
||||
}
|
||||
if err := v.eval(node); err != nil {
|
||||
v.errors = append(v.errors, err)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Visitor) eval(node ast.Node) error {
|
||||
switch t := node.(type) {
|
||||
case *ast.CallExpr:
|
||||
return v.evalExpr(t)
|
||||
case *ast.Ident:
|
||||
return v.evalIdent(t)
|
||||
case *ast.GenDecl:
|
||||
for _, n := range t.Specs {
|
||||
if err := v.eval(n); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case *ast.FuncDecl:
|
||||
if t.Body == nil {
|
||||
return nil
|
||||
}
|
||||
for _, b := range t.Body.List {
|
||||
if err := v.evalStmt(b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *ast.ValueSpec:
|
||||
for _, e := range t.Values {
|
||||
if err := v.evalExpr(e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) evalStmt(stmt ast.Stmt) error {
|
||||
switch t := stmt.(type) {
|
||||
case *ast.ExprStmt:
|
||||
return v.evalExpr(t.X)
|
||||
case *ast.AssignStmt:
|
||||
for _, e := range t.Rhs {
|
||||
if err := v.evalArgs(e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) evalExpr(expr ast.Expr) error {
|
||||
switch t := expr.(type) {
|
||||
case *ast.CallExpr:
|
||||
if t.Fun == nil {
|
||||
return nil
|
||||
}
|
||||
for _, a := range t.Args {
|
||||
switch at := a.(type) {
|
||||
case *ast.CallExpr:
|
||||
if sel, ok := t.Fun.(*ast.SelectorExpr); ok {
|
||||
return v.evalSelector(at, sel)
|
||||
}
|
||||
|
||||
if err := v.evalArgs(at); err != nil {
|
||||
return err
|
||||
}
|
||||
case *ast.CompositeLit:
|
||||
for _, e := range at.Elts {
|
||||
if err := v.evalExpr(e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ft, ok := t.Fun.(*ast.SelectorExpr); ok {
|
||||
return v.evalSelector(t, ft)
|
||||
}
|
||||
case *ast.KeyValueExpr:
|
||||
return v.evalExpr(t.Value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) evalArgs(expr ast.Expr) error {
|
||||
switch at := expr.(type) {
|
||||
case *ast.CompositeLit:
|
||||
for _, e := range at.Elts {
|
||||
if err := v.evalExpr(e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case *ast.CallExpr:
|
||||
if at.Fun == nil {
|
||||
return nil
|
||||
}
|
||||
switch st := at.Fun.(type) {
|
||||
case *ast.SelectorExpr:
|
||||
if err := v.evalSelector(at, st); err != nil {
|
||||
return err
|
||||
}
|
||||
case *ast.Ident:
|
||||
return v.evalIdent(st)
|
||||
}
|
||||
for _, a := range at.Args {
|
||||
if err := v.evalArgs(a); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) evalSelector(expr *ast.CallExpr, sel *ast.SelectorExpr) error {
|
||||
x, ok := sel.X.(*ast.Ident)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if x.Name == "packr" {
|
||||
switch sel.Sel.Name {
|
||||
case "New":
|
||||
if len(expr.Args) != 2 {
|
||||
return fmt.Errorf("`New` requires two arguments")
|
||||
}
|
||||
|
||||
zz := func(e ast.Expr) (string, error) {
|
||||
switch at := e.(type) {
|
||||
case *ast.Ident:
|
||||
switch at.Obj.Kind {
|
||||
case ast.Var:
|
||||
if as, ok := at.Obj.Decl.(*ast.AssignStmt); ok {
|
||||
return v.fromVariable(as)
|
||||
}
|
||||
case ast.Con:
|
||||
if vs, ok := at.Obj.Decl.(*ast.ValueSpec); ok {
|
||||
return v.fromConstant(vs)
|
||||
}
|
||||
}
|
||||
return "", v.evalIdent(at)
|
||||
case *ast.BasicLit:
|
||||
return at.Value, nil
|
||||
case *ast.CallExpr:
|
||||
return "", v.evalExpr(at)
|
||||
}
|
||||
return "", fmt.Errorf("can't handle %T", e)
|
||||
}
|
||||
|
||||
k1, err := zz(expr.Args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k2, err := zz(expr.Args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.addBox(k1, k2)
|
||||
|
||||
return nil
|
||||
case "NewBox":
|
||||
for _, e := range expr.Args {
|
||||
switch at := e.(type) {
|
||||
case *ast.Ident:
|
||||
switch at.Obj.Kind {
|
||||
case ast.Var:
|
||||
if as, ok := at.Obj.Decl.(*ast.AssignStmt); ok {
|
||||
v.addVariable("", as)
|
||||
}
|
||||
case ast.Con:
|
||||
if vs, ok := at.Obj.Decl.(*ast.ValueSpec); ok {
|
||||
v.addConstant("", vs)
|
||||
}
|
||||
}
|
||||
return v.evalIdent(at)
|
||||
case *ast.BasicLit:
|
||||
v.addBox("", at.Value)
|
||||
case *ast.CallExpr:
|
||||
return v.evalExpr(at)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) evalIdent(i *ast.Ident) error {
|
||||
if i.Obj == nil {
|
||||
return nil
|
||||
}
|
||||
if s, ok := i.Obj.Decl.(*ast.AssignStmt); ok {
|
||||
return v.evalStmt(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) addBox(name string, path string) {
|
||||
if len(name) == 0 {
|
||||
name = path
|
||||
}
|
||||
name = strings.Replace(name, "\"", "", -1)
|
||||
path = strings.Replace(path, "\"", "", -1)
|
||||
abs := path
|
||||
if _, ok := v.boxes[name]; !ok {
|
||||
box := NewBox(name, path)
|
||||
box.Package = v.Package
|
||||
|
||||
pd := filepath.Dir(v.File.Name())
|
||||
pwd, _ := os.Getwd()
|
||||
if !filepath.IsAbs(pd) {
|
||||
pd = filepath.Join(pwd, pd)
|
||||
}
|
||||
box.PackageDir = pd
|
||||
|
||||
if !filepath.IsAbs(abs) {
|
||||
abs = filepath.Join(pd, abs)
|
||||
}
|
||||
box.AbsPath = abs
|
||||
v.boxes[name] = box
|
||||
}
|
||||
}
|
||||
func (v *Visitor) fromVariable(as *ast.AssignStmt) (string, error) {
|
||||
if len(as.Rhs) == 1 {
|
||||
if bs, ok := as.Rhs[0].(*ast.BasicLit); ok {
|
||||
return bs.Value, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("unable to find value from variable %v", as)
|
||||
}
|
||||
|
||||
func (v *Visitor) addVariable(bn string, as *ast.AssignStmt) error {
|
||||
bv, err := v.fromVariable(as)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if len(bn) == 0 {
|
||||
bn = bv
|
||||
}
|
||||
v.addBox(bn, bv)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Visitor) fromConstant(vs *ast.ValueSpec) (string, error) {
|
||||
if len(vs.Values) == 1 {
|
||||
if bs, ok := vs.Values[0].(*ast.BasicLit); ok {
|
||||
return bs.Value, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("unable to find value from constant %v", vs)
|
||||
}
|
||||
|
||||
func (v *Visitor) addConstant(bn string, vs *ast.ValueSpec) error {
|
||||
if len(vs.Values) == 1 {
|
||||
if bs, ok := vs.Values[0].(*ast.BasicLit); ok {
|
||||
bv := bs.Value
|
||||
if len(bn) == 0 {
|
||||
bn = bv
|
||||
}
|
||||
v.addBox(bn, bv)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user