aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/gobuffalo/packr/builder
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gobuffalo/packr/builder')
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/box.go76
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/builder.go168
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/clean.go32
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/file.go10
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/pkg.go7
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/tmpl.go18
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/visitor.go248
7 files changed, 559 insertions, 0 deletions
diff --git a/vendor/github.com/gobuffalo/packr/builder/box.go b/vendor/github.com/gobuffalo/packr/builder/box.go
new file mode 100644
index 0000000..8490455
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/box.go
@@ -0,0 +1,76 @@
+package builder
+
+import (
+ "bytes"
+ "compress/gzip"
+ "encoding/json"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+type box struct {
+ Name string
+ Files []file
+ compress bool
+}
+
+func (b *box) Walk(root string) error {
+ root, err := filepath.EvalSymlinks(root)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ if _, err := os.Stat(root); err != nil {
+ // return nil
+ return errors.Errorf("could not find folder for box: %s", root)
+ }
+ return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+ if info == nil || info.IsDir() || strings.HasSuffix(info.Name(), "-packr.go") {
+ return nil
+ }
+ name := strings.Replace(path, root+string(os.PathSeparator), "", 1)
+ name = strings.Replace(name, "\\", "/", -1)
+ f := file{
+ Name: name,
+ }
+
+ DebugLog("packing file %s\n", f.Name)
+
+ bb, err := ioutil.ReadFile(path)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ if b.compress {
+ bb, err = compressFile(bb)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ }
+ bb, err = json.Marshal(bb)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ f.Contents = strings.Replace(string(bb), "\"", "\\\"", -1)
+
+ DebugLog("packed file %s\n", f.Name)
+ b.Files = append(b.Files, f)
+ return nil
+ })
+}
+
+func compressFile(bb []byte) ([]byte, error) {
+ var buf bytes.Buffer
+ writer := gzip.NewWriter(&buf)
+ _, err := writer.Write(bb)
+ if err != nil {
+ return bb, errors.WithStack(err)
+ }
+ err = writer.Close()
+ if err != nil {
+ return bb, errors.WithStack(err)
+ }
+ return buf.Bytes(), nil
+}
diff --git a/vendor/github.com/gobuffalo/packr/builder/builder.go b/vendor/github.com/gobuffalo/packr/builder/builder.go
new file mode 100644
index 0000000..c689500
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/builder.go
@@ -0,0 +1,168 @@
+package builder
+
+import (
+ "context"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "sync"
+ "text/template"
+
+ "github.com/pkg/errors"
+ "golang.org/x/sync/errgroup"
+)
+
+var DebugLog func(string, ...interface{})
+
+func init() {
+ DebugLog = func(string, ...interface{}) {}
+}
+
+var invalidFilePattern = regexp.MustCompile(`(_test|-packr).go$`)
+
+// Builder scans folders/files looking for `packr.NewBox` and then compiling
+// the required static files into `<package-name>-packr.go` files so they can
+// be built into Go binaries.
+type Builder struct {
+ context.Context
+ RootPath string
+ IgnoredBoxes []string
+ IgnoredFolders []string
+ pkgs map[string]pkg
+ moot *sync.Mutex
+ Compress bool
+}
+
+// Run the builder.
+func (b *Builder) Run() error {
+ wg := &errgroup.Group{}
+ root, err := filepath.EvalSymlinks(b.RootPath)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+ if info == nil {
+ return filepath.SkipDir
+ }
+
+ base := strings.ToLower(filepath.Base(path))
+ if strings.HasPrefix(base, "_") {
+ return filepath.SkipDir
+ }
+ for _, f := range b.IgnoredFolders {
+ if strings.ToLower(f) == base {
+ return filepath.SkipDir
+ }
+ }
+ if !info.IsDir() {
+ wg.Go(func() error {
+ return b.process(path)
+ })
+ }
+ return nil
+ })
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ if err := wg.Wait(); err != nil {
+ return errors.WithStack(err)
+ }
+ return b.dump()
+}
+
+func (b *Builder) dump() error {
+ for _, p := range b.pkgs {
+ name := filepath.Join(p.Dir, "a_"+p.Name+"-packr.go")
+ f, err := os.Create(name)
+ defer f.Close()
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ t, err := template.New("").Parse(tmpl)
+
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ err = t.Execute(f, p)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ }
+ return nil
+}
+
+func (b *Builder) process(path string) error {
+ ext := filepath.Ext(path)
+ if ext != ".go" || invalidFilePattern.MatchString(path) {
+ return nil
+ }
+
+ v := newVisitor(path)
+ if err := v.Run(); err != nil {
+ return errors.WithStack(err)
+ }
+
+ pk := pkg{
+ Dir: filepath.Dir(path),
+ Boxes: []box{},
+ Name: v.Package,
+ }
+
+ for _, n := range v.Boxes {
+ var ignored bool
+ for _, i := range b.IgnoredBoxes {
+ if n == i {
+ // this is an ignored box
+ ignored = true
+ break
+ }
+ }
+ if ignored {
+ continue
+ }
+ bx := &box{
+ Name: n,
+ Files: []file{},
+ compress: b.Compress,
+ }
+ DebugLog("building box %s\n", bx.Name)
+ p := filepath.Join(pk.Dir, bx.Name)
+ if err := bx.Walk(p); err != nil {
+ return errors.WithStack(err)
+ }
+ if len(bx.Files) > 0 {
+ pk.Boxes = append(pk.Boxes, *bx)
+ }
+ DebugLog("built box %s with %q\n", bx.Name, bx.Files)
+ }
+
+ if len(pk.Boxes) > 0 {
+ b.addPkg(pk)
+ }
+ return nil
+}
+
+func (b *Builder) addPkg(p pkg) {
+ b.moot.Lock()
+ defer b.moot.Unlock()
+ if _, ok := b.pkgs[p.Name]; !ok {
+ b.pkgs[p.Name] = p
+ return
+ }
+ pp := b.pkgs[p.Name]
+ pp.Boxes = append(pp.Boxes, p.Boxes...)
+ b.pkgs[p.Name] = pp
+}
+
+// New Builder with a given context and path
+func New(ctx context.Context, path string) *Builder {
+ return &Builder{
+ Context: ctx,
+ RootPath: path,
+ IgnoredBoxes: []string{},
+ IgnoredFolders: []string{"vendor", ".git", "node_modules", ".idea"},
+ pkgs: map[string]pkg{},
+ moot: &sync.Mutex{},
+ }
+}
diff --git a/vendor/github.com/gobuffalo/packr/builder/clean.go b/vendor/github.com/gobuffalo/packr/builder/clean.go
new file mode 100644
index 0000000..688ebf5
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/clean.go
@@ -0,0 +1,32 @@
+package builder
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+// Clean up an *-packr.go files
+func Clean(root string) {
+ root, _ = filepath.EvalSymlinks(root)
+ filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+ base := filepath.Base(path)
+ if base == ".git" || base == "vendor" || base == "node_modules" {
+ return filepath.SkipDir
+ }
+ if info == nil || info.IsDir() {
+ return nil
+ }
+ if strings.Contains(base, "-packr.go") {
+ err := os.Remove(path)
+ if err != nil {
+ fmt.Println(err)
+ return errors.WithStack(err)
+ }
+ }
+ return nil
+ })
+}
diff --git a/vendor/github.com/gobuffalo/packr/builder/file.go b/vendor/github.com/gobuffalo/packr/builder/file.go
new file mode 100644
index 0000000..d439d49
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/file.go
@@ -0,0 +1,10 @@
+package builder
+
+type file struct {
+ Name string
+ Contents string
+}
+
+func (f file) String() string {
+ return f.Name
+}
diff --git a/vendor/github.com/gobuffalo/packr/builder/pkg.go b/vendor/github.com/gobuffalo/packr/builder/pkg.go
new file mode 100644
index 0000000..fbad2ac
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/pkg.go
@@ -0,0 +1,7 @@
+package builder
+
+type pkg struct {
+ Name string
+ Dir string
+ Boxes []box
+}
diff --git a/vendor/github.com/gobuffalo/packr/builder/tmpl.go b/vendor/github.com/gobuffalo/packr/builder/tmpl.go
new file mode 100644
index 0000000..ffe47c1
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/tmpl.go
@@ -0,0 +1,18 @@
+package builder
+
+var tmpl = `// Code generated by github.com/gobuffalo/packr. DO NOT EDIT
+
+package {{.Name}}
+
+import "github.com/gobuffalo/packr"
+
+// You can use the "packr clean" command to clean up this,
+// and any other packr generated files.
+func init() {
+ {{- range $box := .Boxes }}
+ {{- range .Files }}
+ packr.PackJSONBytes("{{$box.Name}}", "{{.Name}}", "{{.Contents}}")
+ {{- end }}
+ {{- end }}
+}
+`
diff --git a/vendor/github.com/gobuffalo/packr/builder/visitor.go b/vendor/github.com/gobuffalo/packr/builder/visitor.go
new file mode 100644
index 0000000..ea24bde
--- /dev/null
+++ b/vendor/github.com/gobuffalo/packr/builder/visitor.go
@@ -0,0 +1,248 @@
+package builder
+
+import (
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "io/ioutil"
+ "sort"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+type visitor struct {
+ Path string
+ Package string
+ Boxes []string
+ Errors []error
+}
+
+func newVisitor(path string) *visitor {
+ return &visitor{
+ Path: path,
+ Boxes: []string{},
+ Errors: []error{},
+ }
+}
+
+func (v *visitor) Run() error {
+ b, err := ioutil.ReadFile(v.Path)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+
+ fset := token.NewFileSet()
+ file, err := parser.ParseFile(fset, v.Path, string(b), parser.ParseComments)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+
+ v.Package = file.Name.Name
+ ast.Walk(v, file)
+
+ m := map[string]string{}
+ for _, s := range v.Boxes {
+ m[s] = s
+ }
+ v.Boxes = []string{}
+ for k := range m {
+ v.Boxes = append(v.Boxes, k)
+ }
+
+ sort.Strings(v.Boxes)
+
+ if len(v.Errors) > 0 {
+ s := make([]string, len(v.Errors))
+ for i, e := range v.Errors {
+ s[i] = e.Error()
+ }
+ return errors.New(strings.Join(s, "\n"))
+ }
+ return 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 errors.WithStack(err)
+ }
+ }
+ case *ast.FuncDecl:
+ if t.Body == nil {
+ return nil
+ }
+ for _, b := range t.Body.List {
+ if err := v.evalStmt(b); err != nil {
+ return errors.WithStack(err)
+ }
+ }
+ return nil
+ case *ast.ValueSpec:
+ for _, e := range t.Values {
+ if err := v.evalExpr(e); err != nil {
+ return errors.WithStack(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 errors.WithStack(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 errors.WithStack(err)
+ }
+ case *ast.CompositeLit:
+ for _, e := range at.Elts {
+ if err := v.evalExpr(e); err != nil {
+ return errors.WithStack(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 errors.WithStack(err)
+ }
+ }
+ // case *ast.BasicLit:
+ // fmt.Println("evalArgs", at.Value)
+ // v.addBox(at.Value)
+ 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 errors.WithStack(err)
+ }
+ case *ast.Ident:
+ return v.evalIdent(st)
+ }
+ for _, a := range at.Args {
+ if err := v.evalArgs(a); err != nil {
+ return errors.WithStack(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" && sel.Sel.Name == "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(b string) {
+ b = strings.Replace(b, "\"", "", -1)
+ v.Boxes = append(v.Boxes, b)
+}
+
+func (v *visitor) addVariable(as *ast.AssignStmt) error {
+ if len(as.Rhs) == 1 {
+ if bs, ok := as.Rhs[0].(*ast.BasicLit); ok {
+ v.addBox(bs.Value)
+ }
+ }
+ return nil
+}
+
+func (v *visitor) addConstant(vs *ast.ValueSpec) error {
+ if len(vs.Values) == 1 {
+ if bs, ok := vs.Values[0].(*ast.BasicLit); ok {
+ v.addBox(bs.Value)
+ }
+ }
+ return nil
+}