mirror of
https://github.com/golang/go
synced 2024-11-18 16:04:44 -07:00
8b3cccae50
- Removed the StandAlone and Asset root types as they were just there for other vfses to satisfy the FileSystem interface and causing unnecessary confusion. Returning just empty strings in those scenarios now to clarify that it is a dummy placeholder. - Removed the prefix "Fs" from RootType as it was unnecessary. - Using the RootType type to pass down to the html templates instead of converting to string. The templates are capable of converting to the actual string representation when comparing the value. Change-Id: Iadc039f1354ecd814eec0af1e52cdbaaeff0cc89 Reviewed-on: https://go-review.googlesource.com/106196 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package vfs
|
|
|
|
import (
|
|
"fmt"
|
|
"go/build"
|
|
"io/ioutil"
|
|
"os"
|
|
pathpkg "path"
|
|
"path/filepath"
|
|
"runtime"
|
|
)
|
|
|
|
// OS returns an implementation of FileSystem reading from the
|
|
// tree rooted at root. Recording a root is convenient everywhere
|
|
// but necessary on Windows, because the slash-separated path
|
|
// passed to Open has no way to specify a drive letter. Using a root
|
|
// lets code refer to OS(`c:\`), OS(`d:\`) and so on.
|
|
func OS(root string) FileSystem {
|
|
var t RootType
|
|
switch {
|
|
case root == runtime.GOROOT():
|
|
t = RootTypeGoRoot
|
|
case isGoPath(root):
|
|
t = RootTypeGoPath
|
|
}
|
|
return osFS{rootPath: root, rootType: t}
|
|
}
|
|
|
|
type osFS struct {
|
|
rootPath string
|
|
rootType RootType
|
|
}
|
|
|
|
func isGoPath(path string) bool {
|
|
for _, bp := range filepath.SplitList(build.Default.GOPATH) {
|
|
for _, gp := range filepath.SplitList(path) {
|
|
if bp == gp {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (root osFS) String() string { return "os(" + root.rootPath + ")" }
|
|
|
|
// RootType returns the root type for the filesystem.
|
|
//
|
|
// Note that we ignore the path argument because roottype is a property of
|
|
// this filesystem. But for other filesystems, the roottype might need to be
|
|
// dynamically deduced at call time.
|
|
func (root osFS) RootType(path string) RootType {
|
|
return root.rootType
|
|
}
|
|
|
|
func (root osFS) resolve(path string) string {
|
|
// Clean the path so that it cannot possibly begin with ../.
|
|
// If it did, the result of filepath.Join would be outside the
|
|
// tree rooted at root. We probably won't ever see a path
|
|
// with .. in it, but be safe anyway.
|
|
path = pathpkg.Clean("/" + path)
|
|
|
|
return filepath.Join(root.rootPath, path)
|
|
}
|
|
|
|
func (root osFS) Open(path string) (ReadSeekCloser, error) {
|
|
f, err := os.Open(root.resolve(path))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fi, err := f.Stat()
|
|
if err != nil {
|
|
f.Close()
|
|
return nil, err
|
|
}
|
|
if fi.IsDir() {
|
|
f.Close()
|
|
return nil, fmt.Errorf("Open: %s is a directory", path)
|
|
}
|
|
return f, nil
|
|
}
|
|
|
|
func (root osFS) Lstat(path string) (os.FileInfo, error) {
|
|
return os.Lstat(root.resolve(path))
|
|
}
|
|
|
|
func (root osFS) Stat(path string) (os.FileInfo, error) {
|
|
return os.Stat(root.resolve(path))
|
|
}
|
|
|
|
func (root osFS) ReadDir(path string) ([]os.FileInfo, error) {
|
|
return ioutil.ReadDir(root.resolve(path)) // is sorted
|
|
}
|