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  }