aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/gobuffalo/packr/builder/builder.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gobuffalo/packr/builder/builder.go')
-rw-r--r--vendor/github.com/gobuffalo/packr/builder/builder.go168
1 files changed, 168 insertions, 0 deletions
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{},
+ }
+}