Example #1
0
// 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)
}
Example #2
0
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
}
Example #3
0
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)
	}
}
Example #4
0
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
}