tractor.dev/toolkit-go@v0.0.0-20241010005851-214d91207d07/engine/fs/xformfs/fs.go (about) 1 package xformfs 2 3 import ( 4 "fmt" 5 "io" 6 "io/fs" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "tractor.dev/toolkit-go/engine/fs/memfs" 12 "tractor.dev/toolkit-go/engine/fs/watchfs" 13 ) 14 15 // This package is still experimental and was recently pulled from ui/webiew.go 16 // so it has some hardcoded bits, but still not 100% on this idea in general 17 18 func New(fsys fs.FS) *FS { 19 return &FS{FS: fsys} 20 } 21 22 type FS struct { 23 fs.FS 24 xforms []transform 25 } 26 27 type transform struct { 28 suffix string 29 fn func(dst io.Writer, src io.Reader) error 30 } 31 32 func (xfs *FS) Transform(suffix string, fn func(dst io.Writer, src io.Reader) error) { 33 xfs.xforms = append(xfs.xforms, transform{ 34 suffix: suffix, 35 fn: fn, 36 }) 37 } 38 39 func (xfs *FS) Stat(name string) (fs.FileInfo, error) { 40 return fs.Stat(xfs.FS, name) 41 } 42 43 func (xfs *FS) Watch(name string, cfg *watchfs.Config) (*watchfs.Watch, error) { 44 wfs, ok := xfs.FS.(watchfs.WatchFS) 45 if !ok { 46 return nil, fmt.Errorf("not supported") 47 } 48 w, err := wfs.Watch(name, cfg) 49 if filepath.Ext(name) == "" && os.IsNotExist(err) { 50 exts := []string{".js", ".ts", ".tsx", ".jsx"} 51 for _, ext := range exts { 52 w, err = xfs.Watch(name+ext, cfg) 53 if err == nil { 54 break 55 } 56 } 57 } 58 if err != nil { 59 return nil, err 60 } 61 return w, err 62 } 63 64 func (xfs *FS) Open(name string) (fs.File, error) { 65 f, err := xfs.FS.Open(name) 66 if filepath.Ext(name) == "" && os.IsNotExist(err) { 67 exts := []string{".js", ".ts", ".tsx", ".jsx"} 68 for _, ext := range exts { 69 f, err = xfs.Open(name + ext) 70 if err == nil { 71 break 72 } 73 } 74 } 75 if err != nil { 76 return nil, err 77 } 78 79 for _, xform := range xfs.xforms { 80 if strings.HasSuffix(name, xform.suffix) { 81 ff := memfs.NewFileHandle(memfs.CreateFile(name)) 82 if err := xform.fn(ff, f); err != nil { 83 return nil, err 84 } 85 ff.Seek(0, 0) 86 return ff, nil 87 } 88 } 89 return f, nil 90 }