// Bake writes the data for a VFS generated from dir to the given // io.Writer. The extensions argument can be used to limit the // files included in the VFS by their extension. If empty, all // files are included. func Bake(w io.Writer, dir string, extensions []string) error { fs, err := vfs.FS(dir) if err != nil { return err } if len(extensions) > 0 { // Clone the fs and remove files not matching the extension exts := make(map[string]bool) for _, v := range extensions { if v == "" { continue } if v[0] != '.' { v = "." + v } exts[strings.ToLower(v)] = true } mem := vfs.Memory() if err := vfs.Clone(mem, fs); err != nil { return err } err := vfs.Walk(mem, "/", func(fs vfs.VFS, p string, info os.FileInfo, err error) error { if err != nil || info.IsDir() { return err } if !exts[strings.ToLower(path.Ext(p))] { if err := fs.Remove(p); err != nil { return err } } return nil }) if err != nil { return err } fs = mem } vfs.Walk(fs, "/", func(_ vfs.VFS, p string, info os.FileInfo, err error) error { if !info.IsDir() { log.Debugf("baking %s", p) } return nil }) return vfs.WriteTarGzip(w, fs) }
func (app *App) importAssets(included *includedApp) error { im := included.app.assetsManager if !app.shouldImportAssets() { im.SetPrefix(included.prefix + im.Prefix()) return nil } m := app.assetsManager prefix := strings.ToLower(included.name) renames := make(map[string]string) err := vfs.Walk(im.VFS(), "/", func(fs vfs.VFS, p string, info os.FileInfo, err error) error { if err != nil || info.IsDir() { return err } if p != "" && p[0] == '/' { p = p[1:] } log.Debugf("will import asset %v from app %s", p, included.name) src, err := im.Load(p) if err != nil { return err } defer src.Close() seeker, err := assets.Seeker(src) if err != nil { return err } sum := hashutil.Fnv32a(seeker) nonExt := p[:len(p)-len(path.Ext(p))] dest := path.Join(prefix, nonExt+".gen."+sum+path.Ext(p)) renames[p] = dest log.Debugf("importing asset %q as %q", p, dest) if m.Has(dest) { return nil } f, err := m.Create(dest, true) if err != nil { return err } defer f.Close() if _, err := seeker.Seek(0, os.SEEK_SET); err != nil { return err } if _, err := io.Copy(f, seeker); err != nil { return err } return nil }) if err != nil { return err } included.renames = renames return nil }
func makeAssets(ctx *app.Context) { a := ctx.App() if cfg := a.Config(); cfg != nil { cfg.TemplateDebug = false } err := vfs.Walk(a.TemplatesFS(), "/", func(fs vfs.VFS, p string, info os.FileInfo, err error) error { if err != nil || info.IsDir() || p == "" || p[0] == '.' { return err } if _, err := a.LoadTemplate(p); err != nil { log.Errorf("error loading template %s: %s", p, err) } return nil }) if err != nil { log.Errorf("error listing templates: %s", err) } }
func writeBakedFSCode(w io.Writer, opts *bakeOptions, extensions []string) (err error) { if opts.VFS { if _, err = io.WriteString(w, "import \"gnd.la/util/vfsutil\"\n"); err != nil { return err } } var buf bytes.Buffer if err := vfsutil.Bake(&buf, opts.Dir, extensions); err != nil { return err } data := buf.String() var files []string fs, err := vfs.TarGzip(bytes.NewReader(buf.Bytes())) if err != nil { return err } err = vfs.Walk(fs, "/", func(fs vfs.VFS, path string, info os.FileInfo, err error) error { if !info.IsDir() { files = append(files, strings.TrimPrefix(path, "/")) } return err }) if err != nil { return err } if len(files) > 0 { if _, err := fmt.Fprintf(w, "// %s \n", strings.Join(files, ", ")); err != nil { return err } } if _, err := fmt.Fprintf(w, "var %s = ", opts.Name); err != nil { return err } if opts.VFS { _, err = fmt.Fprintf(w, "vfsutil.MustOpenBaked(%q)\n", data) } else { _, err = fmt.Fprintf(w, "%q\n", data) } return err }