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  }