forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/golang.org/x/tools/go/buildutil/fakecontext.go

192 lines
3.3 KiB
Go
Raw Normal View History

2024-05-14 13:07:09 +00:00
// Copyright 2015 The Go Authors. All rights reserved.
2024-05-14 13:07:09 +00:00
// Use of this source code is governed by a BSD-style
2024-05-14 13:07:09 +00:00
// license that can be found in the LICENSE file.
package buildutil
import (
"fmt"
"go/build"
"io"
"os"
"path"
"path/filepath"
"sort"
"strings"
"time"
)
// FakeContext returns a build.Context for the fake file tree specified
2024-05-14 13:07:09 +00:00
// by pkgs, which maps package import paths to a mapping from file base
2024-05-14 13:07:09 +00:00
// names to contents.
2024-05-14 13:07:09 +00:00
//
2024-05-14 13:07:09 +00:00
// The fake Context has a GOROOT of "/go" and no GOPATH, and overrides
2024-05-14 13:07:09 +00:00
// the necessary file access methods to read from memory instead of the
2024-05-14 13:07:09 +00:00
// real file system.
2024-05-14 13:07:09 +00:00
//
2024-05-14 13:07:09 +00:00
// Unlike a real file tree, the fake one has only two levels---packages
2024-05-14 13:07:09 +00:00
// and files---so ReadDir("/go/src/") returns all packages under
2024-05-14 13:07:09 +00:00
// /go/src/ including, for instance, "math" and "math/big".
2024-05-14 13:07:09 +00:00
// ReadDir("/go/src/math/big") would return all the files in the
2024-05-14 13:07:09 +00:00
// "math/big" package.
2024-05-14 13:07:09 +00:00
func FakeContext(pkgs map[string]map[string]string) *build.Context {
2024-05-14 13:07:09 +00:00
clean := func(filename string) string {
2024-05-14 13:07:09 +00:00
f := path.Clean(filepath.ToSlash(filename))
2024-05-14 13:07:09 +00:00
// Removing "/go/src" while respecting segment
2024-05-14 13:07:09 +00:00
// boundaries has this unfortunate corner case:
2024-05-14 13:07:09 +00:00
if f == "/go/src" {
2024-05-14 13:07:09 +00:00
return ""
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return strings.TrimPrefix(f, "/go/src/")
2024-05-14 13:07:09 +00:00
}
ctxt := build.Default // copy
2024-05-14 13:07:09 +00:00
ctxt.GOROOT = "/go"
2024-05-14 13:07:09 +00:00
ctxt.GOPATH = ""
2024-05-14 13:07:09 +00:00
ctxt.Compiler = "gc"
2024-05-14 13:07:09 +00:00
ctxt.IsDir = func(dir string) bool {
2024-05-14 13:07:09 +00:00
dir = clean(dir)
2024-05-14 13:07:09 +00:00
if dir == "" {
2024-05-14 13:07:09 +00:00
return true // needed by (*build.Context).SrcDirs
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return pkgs[dir] != nil
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
2024-05-14 13:07:09 +00:00
dir = clean(dir)
2024-05-14 13:07:09 +00:00
var fis []os.FileInfo
2024-05-14 13:07:09 +00:00
if dir == "" {
2024-05-14 13:07:09 +00:00
// enumerate packages
2024-05-14 13:07:09 +00:00
for importPath := range pkgs {
2024-05-14 13:07:09 +00:00
fis = append(fis, fakeDirInfo(importPath))
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
} else {
2024-05-14 13:07:09 +00:00
// enumerate files of package
2024-05-14 13:07:09 +00:00
for basename := range pkgs[dir] {
2024-05-14 13:07:09 +00:00
fis = append(fis, fakeFileInfo(basename))
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
sort.Sort(byName(fis))
2024-05-14 13:07:09 +00:00
return fis, nil
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
ctxt.OpenFile = func(filename string) (io.ReadCloser, error) {
2024-05-14 13:07:09 +00:00
filename = clean(filename)
2024-05-14 13:07:09 +00:00
dir, base := path.Split(filename)
2024-05-14 13:07:09 +00:00
content, ok := pkgs[path.Clean(dir)][base]
2024-05-14 13:07:09 +00:00
if !ok {
2024-05-14 13:07:09 +00:00
return nil, fmt.Errorf("file not found: %s", filename)
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return io.NopCloser(strings.NewReader(content)), nil
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
ctxt.IsAbsPath = func(path string) bool {
2024-05-14 13:07:09 +00:00
path = filepath.ToSlash(path)
2024-05-14 13:07:09 +00:00
// Don't rely on the default (filepath.Path) since on
2024-05-14 13:07:09 +00:00
// Windows, it reports virtual paths as non-absolute.
2024-05-14 13:07:09 +00:00
return strings.HasPrefix(path, "/")
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return &ctxt
2024-05-14 13:07:09 +00:00
}
type byName []os.FileInfo
func (s byName) Len() int { return len(s) }
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
2024-05-14 13:07:09 +00:00
func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
type fakeFileInfo string
func (fi fakeFileInfo) Name() string { return string(fi) }
func (fakeFileInfo) Sys() interface{} { return nil }
2024-05-14 13:07:09 +00:00
func (fakeFileInfo) ModTime() time.Time { return time.Time{} }
func (fakeFileInfo) IsDir() bool { return false }
func (fakeFileInfo) Size() int64 { return 0 }
func (fakeFileInfo) Mode() os.FileMode { return 0644 }
2024-05-14 13:07:09 +00:00
type fakeDirInfo string
func (fd fakeDirInfo) Name() string { return string(fd) }
func (fakeDirInfo) Sys() interface{} { return nil }
2024-05-14 13:07:09 +00:00
func (fakeDirInfo) ModTime() time.Time { return time.Time{} }
func (fakeDirInfo) IsDir() bool { return true }
func (fakeDirInfo) Size() int64 { return 0 }
func (fakeDirInfo) Mode() os.FileMode { return 0755 }