summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/GeertJohan/go.rice/rice/find.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/GeertJohan/go.rice/rice/find.go')
-rw-r--r--vendor/github.com/GeertJohan/go.rice/rice/find.go150
1 files changed, 150 insertions, 0 deletions
diff --git a/vendor/github.com/GeertJohan/go.rice/rice/find.go b/vendor/github.com/GeertJohan/go.rice/rice/find.go
new file mode 100644
index 00000000..6d78eeaa
--- /dev/null
+++ b/vendor/github.com/GeertJohan/go.rice/rice/find.go
@@ -0,0 +1,150 @@
+package main
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func badArgument(fileset *token.FileSet, p token.Pos) {
+ pos := fileset.Position(p)
+ filename := pos.Filename
+ base, err := os.Getwd()
+ if err == nil {
+ rpath, perr := filepath.Rel(base, pos.Filename)
+ if perr == nil {
+ filename = rpath
+ }
+ }
+ msg := fmt.Sprintf("%s:%d: Error: found call to rice.FindBox, "+
+ "but argument must be a string literal.\n", filename, pos.Line)
+ fmt.Println(msg)
+ os.Exit(1)
+}
+
+func findBoxes(pkg *build.Package) map[string]bool {
+ // create map of boxes to embed
+ var boxMap = make(map[string]bool)
+
+ // create one list of files for this package
+ filenames := make([]string, 0, len(pkg.GoFiles)+len(pkg.CgoFiles))
+ filenames = append(filenames, pkg.GoFiles...)
+ filenames = append(filenames, pkg.CgoFiles...)
+
+ // loop over files, search for rice.FindBox(..) calls
+ for _, filename := range filenames {
+ // find full filepath
+ fullpath := filepath.Join(pkg.Dir, filename)
+ if strings.HasSuffix(filename, "rice-box.go") {
+ // Ignore *.rice-box.go files
+ verbosef("skipping file %q\n", fullpath)
+ continue
+ }
+ verbosef("scanning file %q\n", fullpath)
+
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, fullpath, nil, 0)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ var riceIsImported bool
+ ricePkgName := "rice"
+ for _, imp := range f.Imports {
+ if strings.HasSuffix(imp.Path.Value, "go.rice\"") {
+ if imp.Name != nil {
+ ricePkgName = imp.Name.Name
+ }
+ riceIsImported = true
+ break
+ }
+ }
+ if !riceIsImported {
+ // Rice wasn't imported, so we won't find a box.
+ continue
+ }
+ if ricePkgName == "_" {
+ // Rice pkg is unnamed, so we won't find a box.
+ continue
+ }
+
+ // Inspect AST, looking for calls to (Must)?FindBox.
+ // First parameter of the func must be a basic literal.
+ // Identifiers won't be resolved.
+ var nextIdentIsBoxFunc bool
+ var nextBasicLitParamIsBoxName bool
+ var boxCall token.Pos
+ var variableToRemember string
+ var validVariablesForBoxes map[string]bool = make(map[string]bool)
+
+ ast.Inspect(f, func(node ast.Node) bool {
+ if node == nil {
+ return false
+ }
+ switch x := node.(type) {
+ // this case fixes the var := func() style assignments, not assignments to vars declared separately from the assignment.
+ case *ast.AssignStmt:
+ var assign = node.(*ast.AssignStmt)
+ name, found := assign.Lhs[0].(*ast.Ident)
+ if found {
+ variableToRemember = name.Name
+ composite, first := assign.Rhs[0].(*ast.CompositeLit)
+ if first {
+ riceSelector, second := composite.Type.(*ast.SelectorExpr)
+
+ if second {
+ callCorrect := riceSelector.Sel.Name == "Config"
+ packageName, third := riceSelector.X.(*ast.Ident)
+
+ if third && callCorrect && packageName.Name == ricePkgName {
+ validVariablesForBoxes[name.Name] = true
+ verbosef("\tfound variable, saving to scan for boxes: %q\n", name.Name)
+ }
+ }
+ }
+ }
+ case *ast.Ident:
+ if nextIdentIsBoxFunc || ricePkgName == "." {
+ nextIdentIsBoxFunc = false
+ if x.Name == "FindBox" || x.Name == "MustFindBox" {
+ nextBasicLitParamIsBoxName = true
+ boxCall = x.Pos()
+ }
+ } else {
+ if x.Name == ricePkgName || validVariablesForBoxes[x.Name] {
+ nextIdentIsBoxFunc = true
+ }
+ }
+ case *ast.BasicLit:
+ if nextBasicLitParamIsBoxName {
+ if x.Kind == token.STRING {
+ nextBasicLitParamIsBoxName = false
+ // trim "" or ``
+ name := x.Value[1 : len(x.Value)-1]
+ boxMap[name] = true
+ verbosef("\tfound box %q\n", name)
+ } else {
+ badArgument(fset, boxCall)
+ }
+ }
+
+ default:
+ if nextIdentIsBoxFunc {
+ nextIdentIsBoxFunc = false
+ }
+ if nextBasicLitParamIsBoxName {
+ badArgument(fset, boxCall)
+ }
+ }
+ return true
+ })
+ }
+
+ return boxMap
+}