mirror of
https://github.com/go-task/task.git
synced 2026-06-15 20:01:40 +00:00
Do vendoring
This commit is contained in:
25
vendor/github.com/mattn/go-zglob/README.md
generated
vendored
Normal file
25
vendor/github.com/mattn/go-zglob/README.md
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# go-zglob
|
||||
|
||||
[](https://travis-ci.org/mattn/go-zglob)
|
||||
|
||||
zglob
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
matches, err := zglob.Glob(`./foo/b*/**/z*.txt`)
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-zglob
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
||||
172
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk.go
generated
vendored
Normal file
172
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk.go
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// A faster implementation of filepath.Walk.
|
||||
//
|
||||
// filepath.Walk's design necessarily calls os.Lstat on each file,
|
||||
// even if the caller needs less info. And goimports only need to know
|
||||
// the type of each file. The kernel interface provides the type in
|
||||
// the Readdir call but the standard library ignored it.
|
||||
// fastwalk_unix.go contains a fork of the syscall routines.
|
||||
//
|
||||
// See golang.org/issue/16399
|
||||
|
||||
package fastwalk
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// traverseLink is a sentinel error for fastWalk, similar to filepath.SkipDir.
|
||||
var traverseLink = errors.New("traverse symlink, assuming target is a directory")
|
||||
|
||||
// FastWalk walks the file tree rooted at root, calling walkFn for
|
||||
// each file or directory in the tree, including root.
|
||||
//
|
||||
// If fastWalk returns filepath.SkipDir, the directory is skipped.
|
||||
//
|
||||
// Unlike filepath.Walk:
|
||||
// * file stat calls must be done by the user.
|
||||
// The only provided metadata is the file type, which does not include
|
||||
// any permission bits.
|
||||
// * multiple goroutines stat the filesystem concurrently. The provided
|
||||
// walkFn must be safe for concurrent use.
|
||||
// * fastWalk can follow symlinks if walkFn returns the traverseLink
|
||||
// sentinel error. It is the walkFn's responsibility to prevent
|
||||
// fastWalk from going into symlink cycles.
|
||||
func FastWalk(root string, walkFn func(path string, typ os.FileMode) error) error {
|
||||
// TODO(bradfitz): make numWorkers configurable? We used a
|
||||
// minimum of 4 to give the kernel more info about multiple
|
||||
// things we want, in hopes its I/O scheduling can take
|
||||
// advantage of that. Hopefully most are in cache. Maybe 4 is
|
||||
// even too low of a minimum. Profile more.
|
||||
numWorkers := 4
|
||||
if n := runtime.NumCPU(); n > numWorkers {
|
||||
numWorkers = n
|
||||
}
|
||||
w := &walker{
|
||||
fn: walkFn,
|
||||
enqueuec: make(chan walkItem, numWorkers), // buffered for performance
|
||||
workc: make(chan walkItem, numWorkers), // buffered for performance
|
||||
donec: make(chan struct{}),
|
||||
|
||||
// buffered for correctness & not leaking goroutines:
|
||||
resc: make(chan error, numWorkers),
|
||||
}
|
||||
defer close(w.donec)
|
||||
// TODO(bradfitz): start the workers as needed? maybe not worth it.
|
||||
for i := 0; i < numWorkers; i++ {
|
||||
go w.doWork()
|
||||
}
|
||||
todo := []walkItem{{dir: root}}
|
||||
out := 0
|
||||
for {
|
||||
workc := w.workc
|
||||
var workItem walkItem
|
||||
if len(todo) == 0 {
|
||||
workc = nil
|
||||
} else {
|
||||
workItem = todo[len(todo)-1]
|
||||
}
|
||||
select {
|
||||
case workc <- workItem:
|
||||
todo = todo[:len(todo)-1]
|
||||
out++
|
||||
case it := <-w.enqueuec:
|
||||
todo = append(todo, it)
|
||||
case err := <-w.resc:
|
||||
out--
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if out == 0 && len(todo) == 0 {
|
||||
// It's safe to quit here, as long as the buffered
|
||||
// enqueue channel isn't also readable, which might
|
||||
// happen if the worker sends both another unit of
|
||||
// work and its result before the other select was
|
||||
// scheduled and both w.resc and w.enqueuec were
|
||||
// readable.
|
||||
select {
|
||||
case it := <-w.enqueuec:
|
||||
todo = append(todo, it)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// doWork reads directories as instructed (via workc) and runs the
|
||||
// user's callback function.
|
||||
func (w *walker) doWork() {
|
||||
for {
|
||||
select {
|
||||
case <-w.donec:
|
||||
return
|
||||
case it := <-w.workc:
|
||||
w.resc <- w.walk(it.dir, !it.callbackDone)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type walker struct {
|
||||
fn func(path string, typ os.FileMode) error
|
||||
|
||||
donec chan struct{} // closed on fastWalk's return
|
||||
workc chan walkItem // to workers
|
||||
enqueuec chan walkItem // from workers
|
||||
resc chan error // from workers
|
||||
}
|
||||
|
||||
type walkItem struct {
|
||||
dir string
|
||||
callbackDone bool // callback already called; don't do it again
|
||||
}
|
||||
|
||||
func (w *walker) enqueue(it walkItem) {
|
||||
select {
|
||||
case w.enqueuec <- it:
|
||||
case <-w.donec:
|
||||
}
|
||||
}
|
||||
|
||||
func (w *walker) onDirEnt(dirName, baseName string, typ os.FileMode) error {
|
||||
joined := dirName + string(os.PathSeparator) + baseName
|
||||
if typ == os.ModeDir {
|
||||
w.enqueue(walkItem{dir: joined})
|
||||
return nil
|
||||
}
|
||||
|
||||
err := w.fn(joined, typ)
|
||||
if typ == os.ModeSymlink {
|
||||
if err == traverseLink {
|
||||
// Set callbackDone so we don't call it twice for both the
|
||||
// symlink-as-symlink and the symlink-as-directory later:
|
||||
w.enqueue(walkItem{dir: joined, callbackDone: true})
|
||||
return nil
|
||||
}
|
||||
if err == filepath.SkipDir {
|
||||
// Permit SkipDir on symlinks too.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (w *walker) walk(root string, runUserCallback bool) error {
|
||||
if runUserCallback {
|
||||
err := w.fn(root, os.ModeDir)
|
||||
if err == filepath.SkipDir {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return readDir(root, w.onDirEnt)
|
||||
}
|
||||
13
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_dirent_fileno.go
generated
vendored
Normal file
13
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_dirent_fileno.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build freebsd openbsd netbsd
|
||||
|
||||
package fastwalk
|
||||
|
||||
import "syscall"
|
||||
|
||||
func direntInode(dirent *syscall.Dirent) uint64 {
|
||||
return uint64(dirent.Fileno)
|
||||
}
|
||||
13
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_dirent_ino.go
generated
vendored
Normal file
13
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_dirent_ino.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build linux,!appengine darwin
|
||||
|
||||
package fastwalk
|
||||
|
||||
import "syscall"
|
||||
|
||||
func direntInode(dirent *syscall.Dirent) uint64 {
|
||||
return uint64(dirent.Ino)
|
||||
}
|
||||
29
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_portable.go
generated
vendored
Normal file
29
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_portable.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build appengine !linux,!darwin,!freebsd,!openbsd,!netbsd
|
||||
|
||||
package fastwalk
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// readDir calls fn for each directory entry in dirName.
|
||||
// It does not descend into directories or follow symlinks.
|
||||
// If fn returns a non-nil error, readDir returns with that error
|
||||
// immediately.
|
||||
func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error {
|
||||
fis, err := ioutil.ReadDir(dirName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fi := range fis {
|
||||
if err := fn(dirName, fi.Name(), fi.Mode()&os.ModeType); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
122
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_unix.go
generated
vendored
Normal file
122
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk_unix.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build linux,!appengine darwin freebsd openbsd netbsd
|
||||
|
||||
package fastwalk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const blockSize = 8 << 10
|
||||
|
||||
// unknownFileMode is a sentinel (and bogus) os.FileMode
|
||||
// value used to represent a syscall.DT_UNKNOWN Dirent.Type.
|
||||
const unknownFileMode os.FileMode = os.ModeNamedPipe | os.ModeSocket | os.ModeDevice
|
||||
|
||||
func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error {
|
||||
fd, err := syscall.Open(dirName, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer syscall.Close(fd)
|
||||
|
||||
// The buffer must be at least a block long.
|
||||
buf := make([]byte, blockSize) // stack-allocated; doesn't escape
|
||||
bufp := 0 // starting read position in buf
|
||||
nbuf := 0 // end valid data in buf
|
||||
for {
|
||||
if bufp >= nbuf {
|
||||
bufp = 0
|
||||
nbuf, err = syscall.ReadDirent(fd, buf)
|
||||
if err != nil {
|
||||
return os.NewSyscallError("readdirent", err)
|
||||
}
|
||||
if nbuf <= 0 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
consumed, name, typ := parseDirEnt(buf[bufp:nbuf])
|
||||
bufp += consumed
|
||||
if name == "" || name == "." || name == ".." {
|
||||
continue
|
||||
}
|
||||
// Fallback for filesystems (like old XFS) that don't
|
||||
// support Dirent.Type and have DT_UNKNOWN (0) there
|
||||
// instead.
|
||||
if typ == unknownFileMode {
|
||||
fi, err := os.Lstat(dirName + "/" + name)
|
||||
if err != nil {
|
||||
// It got deleted in the meantime.
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
typ = fi.Mode() & os.ModeType
|
||||
}
|
||||
if err := fn(dirName, name, typ); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) {
|
||||
// golang.org/issue/15653
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&buf[0]))
|
||||
if v := unsafe.Offsetof(dirent.Reclen) + unsafe.Sizeof(dirent.Reclen); uintptr(len(buf)) < v {
|
||||
panic(fmt.Sprintf("buf size of %d smaller than dirent header size %d", len(buf), v))
|
||||
}
|
||||
if len(buf) < int(dirent.Reclen) {
|
||||
panic(fmt.Sprintf("buf size %d < record length %d", len(buf), dirent.Reclen))
|
||||
}
|
||||
consumed = int(dirent.Reclen)
|
||||
if direntInode(dirent) == 0 { // File absent in directory.
|
||||
return
|
||||
}
|
||||
switch dirent.Type {
|
||||
case syscall.DT_REG:
|
||||
typ = 0
|
||||
case syscall.DT_DIR:
|
||||
typ = os.ModeDir
|
||||
case syscall.DT_LNK:
|
||||
typ = os.ModeSymlink
|
||||
case syscall.DT_BLK:
|
||||
typ = os.ModeDevice
|
||||
case syscall.DT_FIFO:
|
||||
typ = os.ModeNamedPipe
|
||||
case syscall.DT_SOCK:
|
||||
typ = os.ModeSocket
|
||||
case syscall.DT_UNKNOWN:
|
||||
typ = unknownFileMode
|
||||
default:
|
||||
// Skip weird things.
|
||||
// It's probably a DT_WHT (http://lwn.net/Articles/325369/)
|
||||
// or something. Revisit if/when this package is moved outside
|
||||
// of goimports. goimports only cares about regular files,
|
||||
// symlinks, and directories.
|
||||
return
|
||||
}
|
||||
|
||||
nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
nameLen := bytes.IndexByte(nameBuf[:], 0)
|
||||
if nameLen < 0 {
|
||||
panic("failed to find terminating 0 byte in dirent")
|
||||
}
|
||||
|
||||
// Special cases for common things:
|
||||
if nameLen == 1 && nameBuf[0] == '.' {
|
||||
name = "."
|
||||
} else if nameLen == 2 && nameBuf[0] == '.' && nameBuf[1] == '.' {
|
||||
name = ".."
|
||||
} else {
|
||||
name = string(nameBuf[:nameLen])
|
||||
}
|
||||
return
|
||||
}
|
||||
175
vendor/github.com/mattn/go-zglob/zglob.go
generated
vendored
Normal file
175
vendor/github.com/mattn/go-zglob/zglob.go
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
package zglob
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mattn/go-zglob/fastwalk"
|
||||
)
|
||||
|
||||
var (
|
||||
envre = regexp.MustCompile(`^(\$[a-zA-Z][a-zA-Z0-9_]+|\$\([a-zA-Z][a-zA-Z0-9_]+\))$`)
|
||||
mu sync.Mutex
|
||||
)
|
||||
|
||||
type zenv struct {
|
||||
dre *regexp.Regexp
|
||||
fre *regexp.Regexp
|
||||
root string
|
||||
}
|
||||
|
||||
func makePattern(pattern string) (*zenv, error) {
|
||||
globmask := ""
|
||||
root := ""
|
||||
for n, i := range strings.Split(filepath.ToSlash(pattern), "/") {
|
||||
if root == "" && strings.Index(i, "*") != -1 {
|
||||
if globmask == "" {
|
||||
root = "."
|
||||
} else {
|
||||
root = filepath.ToSlash(globmask)
|
||||
}
|
||||
}
|
||||
if n == 0 && i == "~" {
|
||||
if runtime.GOOS == "windows" {
|
||||
i = os.Getenv("USERPROFILE")
|
||||
} else {
|
||||
i = os.Getenv("HOME")
|
||||
}
|
||||
}
|
||||
if envre.MatchString(i) {
|
||||
i = strings.Trim(strings.Trim(os.Getenv(i[1:]), "()"), `"`)
|
||||
}
|
||||
|
||||
globmask = filepath.Join(globmask, i)
|
||||
if n == 0 {
|
||||
if runtime.GOOS == "windows" && filepath.VolumeName(i) != "" {
|
||||
globmask = i + "/"
|
||||
} else if len(globmask) == 0 {
|
||||
globmask = "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
if root == "" {
|
||||
return &zenv{
|
||||
dre: nil,
|
||||
fre: nil,
|
||||
root: "",
|
||||
}, nil
|
||||
}
|
||||
if globmask == "" {
|
||||
globmask = "."
|
||||
}
|
||||
globmask = filepath.ToSlash(filepath.Clean(globmask))
|
||||
|
||||
cc := []rune(globmask)
|
||||
dirmask := ""
|
||||
filemask := ""
|
||||
for i := 0; i < len(cc); i++ {
|
||||
if cc[i] == '*' {
|
||||
if i < len(cc)-2 && cc[i+1] == '*' && cc[i+2] == '/' {
|
||||
filemask += "(.*/)?"
|
||||
dirmask = filemask
|
||||
i += 2
|
||||
} else {
|
||||
filemask += "[^/]*"
|
||||
}
|
||||
} else {
|
||||
c := cc[i]
|
||||
if c == '/' || ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 255 < c {
|
||||
filemask += string(c)
|
||||
} else {
|
||||
filemask += fmt.Sprintf("[\\x%02X]", c)
|
||||
}
|
||||
if c == '/' && dirmask == "" && strings.Index(filemask, "*") != -1 {
|
||||
dirmask = filemask
|
||||
}
|
||||
}
|
||||
}
|
||||
if dirmask == "" {
|
||||
dirmask = filemask
|
||||
}
|
||||
if len(filemask) > 0 && filemask[len(filemask)-1] == '/' {
|
||||
if root == "" {
|
||||
root = filemask
|
||||
}
|
||||
filemask += "[^/]*"
|
||||
}
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
dirmask = "(?i:" + dirmask + ")"
|
||||
filemask = "(?i:" + filemask + ")"
|
||||
}
|
||||
return &zenv{
|
||||
dre: regexp.MustCompile("^" + dirmask),
|
||||
fre: regexp.MustCompile("^" + filemask + "$"),
|
||||
root: filepath.Clean(root),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Glob(pattern string) ([]string, error) {
|
||||
zenv, err := makePattern(pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if zenv.root == "" {
|
||||
_, err := os.Stat(pattern)
|
||||
if err != nil {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return []string{pattern}, nil
|
||||
}
|
||||
relative := !filepath.IsAbs(pattern)
|
||||
matches := []string{}
|
||||
|
||||
fastwalk.FastWalk(zenv.root, func(path string, info os.FileMode) error {
|
||||
if zenv.root == "." && len(zenv.root) < len(path) {
|
||||
path = path[len(zenv.root)+1:]
|
||||
}
|
||||
path = filepath.ToSlash(path)
|
||||
|
||||
if info.IsDir() {
|
||||
if path == "." || len(path) <= len(zenv.root) {
|
||||
return nil
|
||||
}
|
||||
if !zenv.dre.MatchString(path + "/") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
|
||||
if zenv.fre.MatchString(path) {
|
||||
if relative && filepath.IsAbs(path) {
|
||||
path = path[len(zenv.root)+1:]
|
||||
}
|
||||
mu.Lock()
|
||||
matches = append(matches, path)
|
||||
mu.Unlock()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
func Match(pattern, name string) (matched bool, err error) {
|
||||
zenv, err := makePattern(pattern)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if zenv.root == "" {
|
||||
return pattern == name, nil
|
||||
}
|
||||
|
||||
name = filepath.ToSlash(name)
|
||||
|
||||
if name == "." || len(name) <= len(zenv.root) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if zenv.fre.MatchString(name) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user