11package pb
22
33import (
4- " embed"
4+ " embed"
5+ " fmt"
6+ " io/fs"
7+ " os"
8+ " path/filepath"
9+
10+ " github.com/pkg/errors"
511)
612
713var (
814 //go:embed *
915 Embed embed.FS
10- )
16+ )
17+
18+ type Opts func(config *embedxConfig)
19+
20+ type embedxConfig struct {
21+ Dir string
22+ FileMatchFunc func(path string) bool
23+ }
24+
25+ func WithDir(dir string) Opts {
26+ return func(config *embedxConfig) {
27+ config.Dir = dir
28+ }
29+ }
30+
31+ func WithFileMatchFunc(fileFilter func(path string) bool) Opts {
32+ return func(config *embedxConfig) {
33+ config.FileMatchFunc = fileFilter
34+ }
35+ }
36+
37+ func WriteToLocal(ef embed.FS , opts ...Opts ) ([]string, error) {
38+ config := &embedxConfig{}
39+
40+ for _, opt := range opts {
41+ opt(config)
42+ }
43+
44+ var fileList []string
45+
46+ err := fs.WalkDir (ef, " ." , func(path string, d fs.DirEntry , err error) error {
47+ if err != nil {
48+ return err
49+ }
50+ if !d.IsDir () {
51+ data, err := ef.ReadFile (path)
52+ if err != nil {
53+ return err
54+ }
55+ if config.Dir != " " {
56+ if stat, err := os.Stat (config.Dir ); err != nil {
57+ if !os.IsExist (err) {
58+ err = os.MkdirAll (config.Dir , 0o755)
59+ if err != nil {
60+ return err
61+ }
62+ }
63+ } else {
64+ if !stat.IsDir () {
65+ return errors.Errorf (" %s : not a directory" , config.Dir )
66+ }
67+ }
68+ }
69+
70+ var tmpFile *os.File
71+ if config.FileMatchFunc != nil {
72+ if config.FileMatchFunc (path) {
73+ if tmpFile, err = createTemp(config.Dir , path, data); err != nil {
74+ return err
75+ }
76+ }
77+ } else {
78+ if tmpFile, err = createTemp(config.Dir , path, data); err != nil {
79+ return err
80+ }
81+ }
82+ if tmpFile != nil {
83+ fileList = append(fileList, tmpFile.Name ())
84+ }
85+ }
86+ return nil
87+ })
88+ if err != nil {
89+ return nil , err
90+ }
91+ return fileList, nil
92+ }
93+
94+ func createTemp(dir, path string, data []byte) (*os.File , error) {
95+ tmpFile, err := os.CreateTemp (dir, fmt.Sprintf (" *%s " , filepath.Ext (path)))
96+ if err != nil {
97+ return nil , err
98+ }
99+ defer tmpFile.Close ()
100+ if _, err := tmpFile.Write (data); err != nil {
101+ return nil , err
102+ }
103+
104+ return tmpFile, nil
105+ }
0 commit comments