Files
polaris/vendor/github.com/gobuffalo/packr/builder/builder.go
Bobby Brennan 54a4f92695 Pack static assets into packr box for portability
copy config.yaml to docker image

enable external usage of dashboard package

gofmt

fix comment

use packr for assets

add gobuffalo/packr dependency

add dependencies

fix pointer issues

add output-file option
2019-04-18 18:25:16 +00:00

172 lines
3.2 KiB
Go

package builder
import (
"context"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"text/template"
"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 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 {
if info.IsDir() {
return filepath.SkipDir
} else {
return nil
}
}
}
if !info.IsDir() {
wg.Go(func() error {
return b.process(path)
})
}
return nil
})
if err != nil {
return err
}
if err := wg.Wait(); err != nil {
return 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 err
}
t, err := template.New("").Parse(tmpl)
if err != nil {
return err
}
err = t.Execute(f, p)
if err != nil {
return 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 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 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{},
}
}