forked from toolshed/abra
chore: vendor
This commit is contained in:
198
vendor/gotest.tools/v3/fs/path.go
vendored
Normal file
198
vendor/gotest.tools/v3/fs/path.go
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
// resourcePath is an adaptor for resources so they can be used as a Path
|
||||
// with PathOps.
|
||||
type resourcePath struct{}
|
||||
|
||||
func (p *resourcePath) Path() string {
|
||||
return "manifest: not a filesystem path"
|
||||
}
|
||||
|
||||
func (p *resourcePath) Remove() {}
|
||||
|
||||
type filePath struct {
|
||||
resourcePath
|
||||
file *file
|
||||
}
|
||||
|
||||
func (p *filePath) SetContent(content io.ReadCloser) {
|
||||
p.file.content = content
|
||||
}
|
||||
|
||||
func (p *filePath) SetUID(uid uint32) {
|
||||
p.file.uid = uid
|
||||
}
|
||||
|
||||
func (p *filePath) SetGID(gid uint32) {
|
||||
p.file.gid = gid
|
||||
}
|
||||
|
||||
type directoryPath struct {
|
||||
resourcePath
|
||||
directory *directory
|
||||
}
|
||||
|
||||
func (p *directoryPath) SetUID(uid uint32) {
|
||||
p.directory.uid = uid
|
||||
}
|
||||
|
||||
func (p *directoryPath) SetGID(gid uint32) {
|
||||
p.directory.gid = gid
|
||||
}
|
||||
|
||||
func (p *directoryPath) AddSymlink(path, target string) error {
|
||||
p.directory.items[path] = &symlink{
|
||||
resource: newResource(defaultSymlinkMode),
|
||||
target: target,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *directoryPath) AddFile(path string, ops ...PathOp) error {
|
||||
newFile := &file{resource: newResource(0)}
|
||||
p.directory.items[path] = newFile
|
||||
exp := &filePath{file: newFile}
|
||||
return applyPathOps(exp, ops)
|
||||
}
|
||||
|
||||
func (p *directoryPath) AddGlobFiles(glob string, ops ...PathOp) error {
|
||||
newFile := &file{resource: newResource(0)}
|
||||
newFilePath := &filePath{file: newFile}
|
||||
p.directory.filepathGlobs[glob] = newFilePath
|
||||
return applyPathOps(newFilePath, ops)
|
||||
}
|
||||
|
||||
func (p *directoryPath) AddDirectory(path string, ops ...PathOp) error {
|
||||
newDir := newDirectoryWithDefaults()
|
||||
p.directory.items[path] = newDir
|
||||
exp := &directoryPath{directory: newDir}
|
||||
return applyPathOps(exp, ops)
|
||||
}
|
||||
|
||||
// Expected returns a [Manifest] with a directory structured created by ops. The
|
||||
// [PathOp] operations are applied to the manifest as expectations of the
|
||||
// filesystem structure and properties.
|
||||
func Expected(t assert.TestingT, ops ...PathOp) Manifest {
|
||||
if ht, ok := t.(helperT); ok {
|
||||
ht.Helper()
|
||||
}
|
||||
|
||||
newDir := newDirectoryWithDefaults()
|
||||
e := &directoryPath{directory: newDir}
|
||||
assert.NilError(t, applyPathOps(e, ops))
|
||||
return Manifest{root: newDir}
|
||||
}
|
||||
|
||||
func newDirectoryWithDefaults() *directory {
|
||||
return &directory{
|
||||
resource: newResource(defaultRootDirMode),
|
||||
items: make(map[string]dirEntry),
|
||||
filepathGlobs: make(map[string]*filePath),
|
||||
}
|
||||
}
|
||||
|
||||
func newResource(mode os.FileMode) resource {
|
||||
return resource{
|
||||
mode: mode,
|
||||
uid: currentUID(),
|
||||
gid: currentGID(),
|
||||
}
|
||||
}
|
||||
|
||||
func currentUID() uint32 {
|
||||
return normalizeID(os.Getuid())
|
||||
}
|
||||
|
||||
func currentGID() uint32 {
|
||||
return normalizeID(os.Getgid())
|
||||
}
|
||||
|
||||
func normalizeID(id int) uint32 {
|
||||
// ids will be -1 on windows
|
||||
if id < 0 {
|
||||
return 0
|
||||
}
|
||||
return uint32(id)
|
||||
}
|
||||
|
||||
var anyFileContent = io.NopCloser(bytes.NewReader(nil))
|
||||
|
||||
// MatchAnyFileContent is a [PathOp] that updates a [Manifest] so that the file
|
||||
// at path may contain any content.
|
||||
func MatchAnyFileContent(path Path) error {
|
||||
if m, ok := path.(*filePath); ok {
|
||||
m.SetContent(anyFileContent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MatchContentIgnoreCarriageReturn is a [PathOp] that ignores cariage return
|
||||
// discrepancies.
|
||||
func MatchContentIgnoreCarriageReturn(path Path) error {
|
||||
if m, ok := path.(*filePath); ok {
|
||||
m.file.ignoreCariageReturn = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const anyFile = "*"
|
||||
|
||||
// MatchExtraFiles is a [PathOp] that updates a [Manifest] to allow a directory
|
||||
// to contain unspecified files.
|
||||
func MatchExtraFiles(path Path) error {
|
||||
if m, ok := path.(*directoryPath); ok {
|
||||
return m.AddFile(anyFile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompareResult is the result of comparison.
|
||||
//
|
||||
// See [gotest.tools/v3/assert/cmp.StringResult] for a convenient implementation of
|
||||
// this interface.
|
||||
type CompareResult interface {
|
||||
Success() bool
|
||||
FailureMessage() string
|
||||
}
|
||||
|
||||
// MatchFileContent is a [PathOp] that updates a [Manifest] to use the provided
|
||||
// function to determine if a file's content matches the expectation.
|
||||
func MatchFileContent(f func([]byte) CompareResult) PathOp {
|
||||
return func(path Path) error {
|
||||
if m, ok := path.(*filePath); ok {
|
||||
m.file.compareContentFunc = f
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MatchFilesWithGlob is a [PathOp] that updates a [Manifest] to match files using
|
||||
// glob pattern, and check them using the ops.
|
||||
func MatchFilesWithGlob(glob string, ops ...PathOp) PathOp {
|
||||
return func(path Path) error {
|
||||
if m, ok := path.(*directoryPath); ok {
|
||||
return m.AddGlobFiles(glob, ops...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// anyFileMode is represented by uint32_max
|
||||
const anyFileMode os.FileMode = 4294967295
|
||||
|
||||
// MatchAnyFileMode is a [PathOp] that updates a [Manifest] so that the resource at path
|
||||
// will match any file mode.
|
||||
func MatchAnyFileMode(path Path) error {
|
||||
if m, ok := path.(manifestResource); ok {
|
||||
m.SetMode(anyFileMode)
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user