github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/build/vfs.go (about) 1 package build 2 3 import ( 4 "io" 5 "net/http" 6 "os" 7 "path" 8 "path/filepath" 9 "strings" 10 ) 11 12 // vfs is a convenience wrapper around http.FileSystem that provides accessor 13 // methods required by go/build.Context. 14 type vfs struct{ http.FileSystem } 15 16 func (fs vfs) IsDir(name string) bool { 17 name = filepath.ToSlash(name) 18 dir, err := fs.Open(name) 19 if err != nil { 20 return false 21 } 22 defer dir.Close() 23 info, err := dir.Stat() 24 if err != nil { 25 return false 26 } 27 return info.IsDir() 28 } 29 30 func (fs vfs) ReadDir(name string) (fi []os.FileInfo, err error) { 31 name = filepath.ToSlash(name) 32 dir, err := fs.Open(name) 33 if err != nil { 34 return nil, err 35 } 36 defer dir.Close() 37 return dir.Readdir(0) 38 } 39 40 func (fs vfs) OpenFile(name string) (r io.ReadCloser, err error) { 41 name = filepath.ToSlash(name) 42 return fs.Open(name) 43 } 44 45 func splitPathList(list string) []string { 46 if list == "" { 47 return nil 48 } 49 const pathListSeparator = ":" // UNIX style 50 return strings.Split(list, pathListSeparator) 51 } 52 53 // hasSubdir reports whether dir is lexically a subdirectory of 54 // root, perhaps multiple levels below. It does not try to check 55 // whether dir exists. 56 // If so, hasSubdir sets rel to a slash-separated path that 57 // can be joined to root to produce a path equivalent to dir. 58 func hasSubdir(root, dir string) (rel string, ok bool) { 59 // Implementation based on golang.org/x/tools/go/buildutil. 60 const sep = "/" // UNIX style 61 root = path.Clean(root) 62 if !strings.HasSuffix(root, sep) { 63 root += sep 64 } 65 66 dir = path.Clean(dir) 67 if !strings.HasPrefix(dir, root) { 68 return "", false 69 } 70 71 return dir[len(root):], true 72 } 73 74 // withPrefix implements http.FileSystem, which places the underlying FS under 75 // the given prefix path. 76 type withPrefix struct { 77 fs http.FileSystem 78 prefix string 79 } 80 81 func (wp *withPrefix) Open(name string) (http.File, error) { 82 name = filepath.ToSlash(name) 83 prefix := filepath.ToSlash(wp.prefix) 84 if !strings.HasPrefix(name, prefix) { 85 return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist} 86 } 87 f, err := wp.fs.Open(strings.TrimPrefix(name, prefix)) 88 if err != nil { 89 return nil, &os.PathError{Op: "open", Path: name, Err: err} 90 } 91 return f, nil 92 }