This commit is contained in:
bel
2020-01-13 03:37:51 +00:00
commit c8eb52f9ba
2023 changed files with 702080 additions and 0 deletions

2
.rclone_repo/vendor/github.com/a8m/tree/.gitignore generated vendored Executable file
View File

@@ -0,0 +1,2 @@
draft
coverage

12
.rclone_repo/vendor/github.com/a8m/tree/.travis.yml generated vendored Executable file
View File

@@ -0,0 +1,12 @@
language: go
sudo: false
go:
- 1.6.4
- 1.7.4
- 1.8.3
- tip
install:
- go get -t -v ./...
script:
- go test -v ./...
- ./compileall.sh

21
.rclone_repo/vendor/github.com/a8m/tree/LICENSE generated vendored Executable file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2015-2017 Ariel Mashraki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

43
.rclone_repo/vendor/github.com/a8m/tree/README.md generated vendored Executable file
View File

@@ -0,0 +1,43 @@
tree [![Build status][travis-image]][travis-url] [![License][license-image]][license-url]
---
> An implementation of the [`tree`](http://mama.indstate.edu/users/ice/tree/) command written in Go, that can be used programmatically.
<img src="https://raw.githubusercontent.com/a8m/tree/assets/assets/tree.png" height="300" alt="tree command">
#### Installation:
```sh
$ go get github.com/a8m/tree/cmd/tree
```
#### How to use `tree` programmatically ?
You can take a look on [`cmd/tree`](https://github.com/a8m/tree/blob/master/cmd/tree/tree.go), and [s3tree](http://github.com/a8m/s3tree) or see the example below.
```go
import (
"github.com/a8m/tree"
)
func main() {
opts := &tree.Options{
// Fs, and OutFile are required fields.
// fs should implement the tree file-system interface(see: tree.Fs),
// and OutFile should be type io.Writer
Fs: fs,
OutFile: os.Stdout,
// ...
}
inf.New("root-dir")
// Visit all nodes recursively
inf.Visit(opts)
// Print nodes
inf.Print(opts)
}
```
### License
MIT
[travis-image]: https://img.shields.io/travis/a8m/tree.svg?style=flat-square
[travis-url]: https://travis-ci.org/a8m/tree
[license-image]: http://img.shields.io/npm/l/deep-keys.svg?style=flat-square
[license-url]: LICENSE

74
.rclone_repo/vendor/github.com/a8m/tree/color.go generated vendored Executable file
View File

@@ -0,0 +1,74 @@
package tree
import (
"fmt"
"os"
"path/filepath"
"strings"
)
const Escape = "\x1b"
const (
Reset int = 0
// Not used, remove.
Bold int = 1
Black int = iota + 28
Red
Green
Yellow
Blue
Magenta
Cyan
White
)
// ANSIColor
func ANSIColor(node *Node, s string) string {
var style string
var mode = node.Mode()
var ext = filepath.Ext(node.Name())
switch {
case contains([]string{".bat", ".btm", ".cmd", ".com", ".dll", ".exe"}, ext):
style = "1;32"
case contains([]string{".arj", ".bz2", ".deb", ".gz", ".lzh", ".rpm",
".tar", ".taz", ".tb2", ".tbz2", ".tbz", ".tgz", ".tz", ".tz2", ".z",
".zip", ".zoo"}, ext):
style = "1;31"
case contains([]string{".asf", ".avi", ".bmp", ".flac", ".gif", ".jpg",
"jpeg", ".m2a", ".m2v", ".mov", ".mp3", ".mpeg", ".mpg", ".ogg", ".ppm",
".rm", ".tga", ".tif", ".wav", ".wmv",
".xbm", ".xpm"}, ext):
style = "1;35"
case node.IsDir() || mode&os.ModeDir != 0:
style = "1;34"
case mode&os.ModeNamedPipe != 0:
style = "40;33"
case mode&os.ModeSocket != 0:
style = "40;1;35"
case mode&os.ModeDevice != 0 || mode&os.ModeCharDevice != 0:
style = "40;1;33"
case mode&os.ModeSymlink != 0:
if _, err := filepath.EvalSymlinks(node.path); err != nil {
style = "40;1;31"
} else {
style = "1;36"
}
case mode&modeExecute != 0:
style = "1;32"
default:
return s
}
return fmt.Sprintf("%s[%sm%s%s[%dm", Escape, style, s, Escape, Reset)
}
// case-insensitive contains helper
func contains(slice []string, str string) bool {
for _, val := range slice {
if val == strings.ToLower(str) {
return true
}
}
return false
}
// TODO: HTMLColor

14
.rclone_repo/vendor/github.com/a8m/tree/compileall.sh generated vendored Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
go tool dist list >/dev/null || {
echo 1>&2 "go tool dist list not supported - can't check compile"
exit 0
}
while read -r line; do
parts=(${line//\// })
export GOOS=${parts[0]}
export GOARCH=${parts[1]}
echo Try GOOS=${GOOS} GOARCH=${GOARCH}
go install
done < <(go tool dist list)

18
.rclone_repo/vendor/github.com/a8m/tree/csort_bsd.go generated vendored Executable file
View File

@@ -0,0 +1,18 @@
//+build darwin freebsd netbsd
package tree
import (
"os"
"syscall"
)
func CTimeSort(f1, f2 os.FileInfo) bool {
s1, ok1 := f1.Sys().(*syscall.Stat_t)
s2, ok2 := f2.Sys().(*syscall.Stat_t)
// If this type of node isn't an os node then revert to ModSort
if !ok1 || !ok2 {
return ModSort(f1, f2)
}
return s1.Ctimespec.Sec < s2.Ctimespec.Sec
}

6
.rclone_repo/vendor/github.com/a8m/tree/csort_generic.go generated vendored Executable file
View File

@@ -0,0 +1,6 @@
//+build !linux,!openbsd,!dragonfly,!android,!solaris,!darwin,!freebsd,!netbsd
package tree
// CtimeSort for unsupported OS - just compare ModTime
var CTimeSort = ModSort

18
.rclone_repo/vendor/github.com/a8m/tree/csort_unix.go generated vendored Executable file
View File

@@ -0,0 +1,18 @@
//+build linux openbsd dragonfly android solaris
package tree
import (
"os"
"syscall"
)
func CTimeSort(f1, f2 os.FileInfo) bool {
s1, ok1 := f1.Sys().(*syscall.Stat_t)
s2, ok2 := f2.Sys().(*syscall.Stat_t)
// If this type of node isn't an os node then revert to ModSort
if !ok1 || !ok2 {
return ModSort(f1, f2)
}
return s1.Ctim.Sec < s2.Ctim.Sec
}

7
.rclone_repo/vendor/github.com/a8m/tree/modes_bsd.go generated vendored Executable file
View File

@@ -0,0 +1,7 @@
//+build dragonfly freebsd openbsd solaris windows
package tree
import "syscall"
const modeExecute = syscall.S_IXUSR

7
.rclone_repo/vendor/github.com/a8m/tree/modes_unix.go generated vendored Executable file
View File

@@ -0,0 +1,7 @@
//+build android darwin linux nacl netbsd
package tree
import "syscall"
const modeExecute = syscall.S_IXUSR | syscall.S_IXGRP | syscall.S_IXOTH

View File

@@ -0,0 +1,5 @@
//+build !dragonfly,!freebsd,!openbsd,!solaris,!windows,!android,!darwin,!linux,!nacl,!netbsd
package tree
const modeExecute = 0

399
.rclone_repo/vendor/github.com/a8m/tree/node.go generated vendored Executable file
View File

@@ -0,0 +1,399 @@
package tree
import (
"errors"
"fmt"
"io"
"os"
"os/user"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
)
// Node represent some node in the tree
// contains FileInfo, and its childs
type Node struct {
os.FileInfo
path string
depth int
err error
nodes Nodes
vpaths map[string]bool
}
// List of nodes
type Nodes []*Node
// To use this package programmatically, you must implement this
// interface.
// For example: PTAL on 'cmd/tree/tree.go'
type Fs interface {
Stat(path string) (os.FileInfo, error)
ReadDir(path string) ([]string, error)
}
// Options store the configuration for specific tree.
// Note, that 'Fs', and 'OutFile' are required (OutFile can be os.Stdout).
type Options struct {
Fs Fs
OutFile io.Writer
// List
All bool
DirsOnly bool
FullPath bool
IgnoreCase bool
FollowLink bool
DeepLevel int
Pattern string
IPattern string
// File
ByteSize bool
UnitSize bool
FileMode bool
ShowUid bool
ShowGid bool
LastMod bool
Quotes bool
Inodes bool
Device bool
// Sort
NoSort bool
VerSort bool
ModSort bool
DirSort bool
NameSort bool
SizeSort bool
CTimeSort bool
ReverSort bool
// Graphics
NoIndent bool
Colorize bool
}
// New get path and create new node(root).
func New(path string) *Node {
return &Node{path: path, vpaths: make(map[string]bool)}
}
// Visit all files under the given node.
func (node *Node) Visit(opts *Options) (dirs, files int) {
// visited paths
if path, err := filepath.Abs(node.path); err == nil {
path = filepath.Clean(path)
node.vpaths[path] = true
}
// stat
fi, err := opts.Fs.Stat(node.path)
if err != nil {
node.err = err
return
}
node.FileInfo = fi
if !fi.IsDir() {
return 0, 1
}
// increase dirs only if it's a dir, but not the root.
if node.depth != 0 {
dirs++
}
// DeepLevel option
if opts.DeepLevel > 0 && opts.DeepLevel <= node.depth {
return
}
names, err := opts.Fs.ReadDir(node.path)
if err != nil {
node.err = err
return
}
node.nodes = make(Nodes, 0)
for _, name := range names {
// "all" option
if !opts.All && strings.HasPrefix(name, ".") {
continue
}
nnode := &Node{
path: filepath.Join(node.path, name),
depth: node.depth + 1,
vpaths: node.vpaths,
}
d, f := nnode.Visit(opts)
if nnode.err == nil && !nnode.IsDir() {
// "dirs only" option
if opts.DirsOnly {
continue
}
var rePrefix string
if opts.IgnoreCase {
rePrefix = "(?i)"
}
// Pattern matching
if opts.Pattern != "" {
re, err := regexp.Compile(rePrefix + opts.Pattern)
if err == nil && !re.MatchString(name) {
continue
}
}
// IPattern matching
if opts.IPattern != "" {
re, err := regexp.Compile(rePrefix + opts.IPattern)
if err == nil && re.MatchString(name) {
continue
}
}
}
node.nodes = append(node.nodes, nnode)
dirs, files = dirs+d, files+f
}
// Sorting
if !opts.NoSort {
node.sort(opts)
}
return
}
func (node *Node) sort(opts *Options) {
var fn SortFunc
switch {
case opts.ModSort:
fn = ModSort
case opts.CTimeSort:
fn = CTimeSort
case opts.DirSort:
fn = DirSort
case opts.VerSort:
fn = VerSort
case opts.SizeSort:
fn = SizeSort
case opts.NameSort:
fn = NameSort
default:
fn = NameSort // Default should be sorted, not unsorted.
}
if fn != nil {
if opts.ReverSort {
sort.Sort(sort.Reverse(ByFunc{node.nodes, fn}))
} else {
sort.Sort(ByFunc{node.nodes, fn})
}
}
}
// Print nodes based on the given configuration.
func (node *Node) Print(opts *Options) { node.print("", opts) }
func dirRecursiveSize(opts *Options, node *Node) (size int64, err error) {
if opts.DeepLevel > 0 && node.depth >= opts.DeepLevel {
err = errors.New("Depth too high")
}
for _, nnode := range node.nodes {
if nnode.err != nil {
err = nnode.err
continue
}
if !nnode.IsDir() {
size += nnode.Size()
} else {
nsize, e := dirRecursiveSize(opts, nnode)
size += nsize
if e != nil {
err = e
}
}
}
return
}
func (node *Node) print(indent string, opts *Options) {
if node.err != nil {
err := node.err.Error()
if msgs := strings.Split(err, ": "); len(msgs) > 1 {
err = msgs[1]
}
fmt.Printf("%s [%s]\n", node.path, err)
return
}
if !node.IsDir() {
var props []string
ok, inode, device, uid, gid := getStat(node)
// inodes
if ok && opts.Inodes {
props = append(props, fmt.Sprintf("%d", inode))
}
// device
if ok && opts.Device {
props = append(props, fmt.Sprintf("%3d", device))
}
// Mode
if opts.FileMode {
props = append(props, node.Mode().String())
}
// Owner/Uid
if ok && opts.ShowUid {
uidStr := strconv.Itoa(int(uid))
if u, err := user.LookupId(uidStr); err != nil {
props = append(props, fmt.Sprintf("%-8s", uidStr))
} else {
props = append(props, fmt.Sprintf("%-8s", u.Username))
}
}
// Gorup/Gid
// TODO: support groupname
if ok && opts.ShowGid {
gidStr := strconv.Itoa(int(gid))
props = append(props, fmt.Sprintf("%-4s", gidStr))
}
// Size
if opts.ByteSize || opts.UnitSize {
var size string
if opts.UnitSize {
size = fmt.Sprintf("%4s", formatBytes(node.Size()))
} else {
size = fmt.Sprintf("%11d", node.Size())
}
props = append(props, size)
}
// Last modification
if opts.LastMod {
props = append(props, node.ModTime().Format("Jan 02 15:04"))
}
// Print properties
if len(props) > 0 {
fmt.Fprintf(opts.OutFile, "[%s] ", strings.Join(props, " "))
}
} else {
var props []string
// Size
if opts.ByteSize || opts.UnitSize {
var size string
rsize, err := dirRecursiveSize(opts, node)
if err != nil && rsize <= 0 {
if opts.UnitSize {
size = "????"
} else {
size = "???????????"
}
} else if opts.UnitSize {
size = fmt.Sprintf("%4s", formatBytes(rsize))
} else {
size = fmt.Sprintf("%11d", rsize)
}
props = append(props, size)
}
// Print properties
if len(props) > 0 {
fmt.Fprintf(opts.OutFile, "[%s] ", strings.Join(props, " "))
}
}
// name/path
var name string
if node.depth == 0 || opts.FullPath {
name = node.path
} else {
name = node.Name()
}
// Quotes
if opts.Quotes {
name = fmt.Sprintf("\"%s\"", name)
}
// Colorize
if opts.Colorize {
name = ANSIColor(node, name)
}
// IsSymlink
if node.Mode()&os.ModeSymlink == os.ModeSymlink {
vtarget, err := os.Readlink(node.path)
if err != nil {
vtarget = node.path
}
targetPath, err := filepath.EvalSymlinks(node.path)
if err != nil {
targetPath = vtarget
}
fi, err := opts.Fs.Stat(targetPath)
if opts.Colorize && fi != nil {
vtarget = ANSIColor(&Node{FileInfo: fi, path: vtarget}, vtarget)
}
name = fmt.Sprintf("%s -> %s", name, vtarget)
// Follow symbolic links like directories
if opts.FollowLink {
path, err := filepath.Abs(targetPath)
if err == nil && fi != nil && fi.IsDir() {
if _, ok := node.vpaths[filepath.Clean(path)]; !ok {
inf := &Node{FileInfo: fi, path: targetPath}
inf.vpaths = node.vpaths
inf.Visit(opts)
node.nodes = inf.nodes
} else {
name += " [recursive, not followed]"
}
}
}
}
// Print file details
// the main idea of the print logic came from here: github.com/campoy/tools/tree
fmt.Fprintln(opts.OutFile, name)
add := "│ "
for i, nnode := range node.nodes {
if opts.NoIndent {
add = ""
} else {
if i == len(node.nodes)-1 {
fmt.Fprintf(opts.OutFile, indent+"└── ")
add = " "
} else {
fmt.Fprintf(opts.OutFile, indent+"├── ")
}
}
nnode.print(indent+add, opts)
}
}
const (
_ = iota // ignore first value by assigning to blank identifier
KB int64 = 1 << (10 * iota)
MB
GB
TB
PB
EB
)
// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
func formatBytes(i int64) (result string) {
var n float64
sFmt, eFmt := "%.01f", ""
switch {
case i > EB:
eFmt = "E"
n = float64(i) / float64(EB)
case i > PB:
eFmt = "P"
n = float64(i) / float64(PB)
case i > TB:
eFmt = "T"
n = float64(i) / float64(TB)
case i > GB:
eFmt = "G"
n = float64(i) / float64(GB)
case i > MB:
eFmt = "M"
n = float64(i) / float64(MB)
case i > KB:
eFmt = "K"
n = float64(i) / float64(KB)
default:
sFmt = "%.0f"
n = float64(i)
}
if eFmt != "" && n >= 10 {
sFmt = "%.0f"
}
result = fmt.Sprintf(sFmt+eFmt, n)
result = strings.Trim(result, " ")
return
}

100
.rclone_repo/vendor/github.com/a8m/tree/sort.go generated vendored Executable file
View File

@@ -0,0 +1,100 @@
package tree
import "os"
func (n Nodes) Len() int { return len(n) }
func (n Nodes) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
type ByFunc struct {
Nodes
Fn SortFunc
}
func (b ByFunc) Less(i, j int) bool {
return b.Fn(b.Nodes[i].FileInfo, b.Nodes[j].FileInfo)
}
type SortFunc func(f1, f2 os.FileInfo) bool
func ModSort(f1, f2 os.FileInfo) bool {
return f1.ModTime().Before(f2.ModTime())
}
func DirSort(f1, f2 os.FileInfo) bool {
return f1.IsDir() && !f2.IsDir()
}
func SizeSort(f1, f2 os.FileInfo) bool {
return f1.Size() < f2.Size()
}
func NameSort(f1, f2 os.FileInfo) bool {
return f1.Name() < f2.Name()
}
func VerSort(f1, f2 os.FileInfo) bool {
return NaturalLess(f1.Name(), f2.Name())
}
func isdigit(b byte) bool { return '0' <= b && b <= '9' }
// NaturalLess compares two strings using natural ordering. This means that e.g.
// "abc2" < "abc12".
//
// Non-digit sequences and numbers are compared separately. The former are
// compared bytewise, while the latter are compared numerically (except that
// the number of leading zeros is used as a tie-breaker, so e.g. "2" < "02")
//
// Limitation: only ASCII digits (0-9) are considered.
// Code taken from:
// https://github.com/fvbommel/util/blob/master/sortorder/natsort.go
func NaturalLess(str1, str2 string) bool {
idx1, idx2 := 0, 0
for idx1 < len(str1) && idx2 < len(str2) {
c1, c2 := str1[idx1], str2[idx2]
dig1, dig2 := isdigit(c1), isdigit(c2)
switch {
case dig1 != dig2: // Digits before other characters.
return dig1 // True if LHS is a digit, false if the RHS is one.
case !dig1: // && !dig2, because dig1 == dig2
// UTF-8 compares bytewise-lexicographically, no need to decode
// codepoints.
if c1 != c2 {
return c1 < c2
}
idx1++
idx2++
default: // Digits
// Eat zeros.
for ; idx1 < len(str1) && str1[idx1] == '0'; idx1++ {
}
for ; idx2 < len(str2) && str2[idx2] == '0'; idx2++ {
}
// Eat all digits.
nonZero1, nonZero2 := idx1, idx2
for ; idx1 < len(str1) && isdigit(str1[idx1]); idx1++ {
}
for ; idx2 < len(str2) && isdigit(str2[idx2]); idx2++ {
}
// If lengths of numbers with non-zero prefix differ, the shorter
// one is less.
if len1, len2 := idx1-nonZero1, idx2-nonZero2; len1 != len2 {
return len1 < len2
}
// If they're not equal, string comparison is correct.
if nr1, nr2 := str1[nonZero1:idx1], str2[nonZero2:idx2]; nr1 != nr2 {
return nr1 < nr2
}
// Otherwise, the one with less zeros is less.
// Because everything up to the number is equal, comparing the index
// after the zeros is sufficient.
if nonZero1 != nonZero2 {
return nonZero1 < nonZero2
}
}
// They're identical so far, so continue comparing.
}
// So far they are identical. At least one is ended. If the other continues,
// it sorts last.
return len(str1) < len(str2)
}

20
.rclone_repo/vendor/github.com/a8m/tree/stat_unix.go generated vendored Executable file
View File

@@ -0,0 +1,20 @@
//+build !plan9,!windows
package tree
import (
"os"
"syscall"
)
func getStat(fi os.FileInfo) (ok bool, inode, device, uid, gid uint64) {
sys := fi.Sys()
if sys == nil {
return false, 0, 0, 0, 0
}
stat, ok := sys.(*syscall.Stat_t)
if !ok {
return false, 0, 0, 0, 0
}
return true, uint64(stat.Ino), uint64(stat.Dev), uint64(stat.Uid), uint64(stat.Gid)
}

View File

@@ -0,0 +1,9 @@
//+build plan9 windows
package tree
import "os"
func getStat(fi os.FileInfo) (ok bool, inode, device, uid, gid uint64) {
return false, 0, 0, 0, 0
}