github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/_vendor/src/golang.org/x/tools/godoc/vfs/os.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package vfs 6 7 import ( 8 "fmt" 9 "go/build" 10 "io/ioutil" 11 "os" 12 pathpkg "path" 13 "path/filepath" 14 "runtime" 15 ) 16 17 // OS returns an implementation of FileSystem reading from the 18 // tree rooted at root. Recording a root is convenient everywhere 19 // but necessary on Windows, because the slash-separated path 20 // passed to Open has no way to specify a drive letter. Using a root 21 // lets code refer to OS(`c:\`), OS(`d:\`) and so on. 22 func OS(root string) FileSystem { 23 var t RootType 24 switch { 25 case root == runtime.GOROOT(): 26 t = RootTypeGoRoot 27 case isGoPath(root): 28 t = RootTypeGoPath 29 } 30 return osFS{rootPath: root, rootType: t} 31 } 32 33 type osFS struct { 34 rootPath string 35 rootType RootType 36 } 37 38 func isGoPath(path string) bool { 39 for _, bp := range filepath.SplitList(build.Default.GOPATH) { 40 for _, gp := range filepath.SplitList(path) { 41 if bp == gp { 42 return true 43 } 44 } 45 } 46 return false 47 } 48 49 func (root osFS) String() string { return "os(" + root.rootPath + ")" } 50 51 // RootType returns the root type for the filesystem. 52 // 53 // Note that we ignore the path argument because roottype is a property of 54 // this filesystem. But for other filesystems, the roottype might need to be 55 // dynamically deduced at call time. 56 func (root osFS) RootType(path string) RootType { 57 return root.rootType 58 } 59 60 func (root osFS) resolve(path string) string { 61 // Clean the path so that it cannot possibly begin with ../. 62 // If it did, the result of filepath.Join would be outside the 63 // tree rooted at root. We probably won't ever see a path 64 // with .. in it, but be safe anyway. 65 path = pathpkg.Clean("/" + path) 66 67 return filepath.Join(root.rootPath, path) 68 } 69 70 func (root osFS) Open(path string) (ReadSeekCloser, error) { 71 f, err := os.Open(root.resolve(path)) 72 if err != nil { 73 return nil, err 74 } 75 fi, err := f.Stat() 76 if err != nil { 77 f.Close() 78 return nil, err 79 } 80 if fi.IsDir() { 81 f.Close() 82 return nil, fmt.Errorf("Open: %s is a directory", path) 83 } 84 return f, nil 85 } 86 87 func (root osFS) Lstat(path string) (os.FileInfo, error) { 88 return os.Lstat(root.resolve(path)) 89 } 90 91 func (root osFS) Stat(path string) (os.FileInfo, error) { 92 return os.Stat(root.resolve(path)) 93 } 94 95 func (root osFS) ReadDir(path string) ([]os.FileInfo, error) { 96 return ioutil.ReadDir(root.resolve(path)) // is sorted 97 }