Add support for copying files and folders.
This commit is contained in:
5
vendor/github.com/otiai10/copy/.gitignore
generated
vendored
Normal file
5
vendor/github.com/otiai10/copy/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
test/data.copy
|
||||
coverage.txt
|
||||
vendor
|
||||
.vagrant
|
||||
.idea/
|
21
vendor/github.com/otiai10/copy/LICENSE
generated
vendored
Normal file
21
vendor/github.com/otiai10/copy/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 otiai10
|
||||
|
||||
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.
|
77
vendor/github.com/otiai10/copy/README.md
generated
vendored
Normal file
77
vendor/github.com/otiai10/copy/README.md
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
# copy
|
||||
|
||||
[](https://pkg.go.dev/github.com/otiai10/copy)
|
||||
[](https://github.com/otiai10/copy/actions)
|
||||
[](https://codecov.io/gh/otiai10/copy)
|
||||
[](https://github.com/otiai10/copy/blob/main/LICENSE)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fotiai10%2Fcopy?ref=badge_shield)
|
||||
[](https://github.com/otiai10/copy/actions/workflows/codeql-analysis.yml)
|
||||
[](https://goreportcard.com/report/github.com/otiai10/copy)
|
||||
[](https://pkg.go.dev/github.com/otiai10/copy)
|
||||
[](https://github.com/otiai10/copy/actions/workflows/docker-test.yml)
|
||||
[](https://github.com/otiai10/copy/actions/workflows/vagrant-test.yml)
|
||||
|
||||
`copy` copies directories recursively.
|
||||
|
||||
# Example Usage
|
||||
|
||||
```go
|
||||
err := Copy("your/directory", "your/directory.copy")
|
||||
```
|
||||
|
||||
# Advanced Usage
|
||||
|
||||
```go
|
||||
// Options specifies optional actions on copying.
|
||||
type Options struct {
|
||||
|
||||
// OnSymlink can specify what to do on symlink
|
||||
OnSymlink func(src string) SymlinkAction
|
||||
|
||||
// OnDirExists can specify what to do when there is a directory already existing in destination.
|
||||
OnDirExists func(src, dest string) DirExistsAction
|
||||
|
||||
// Skip can specify which files should be skipped
|
||||
Skip func(src string) (bool, error)
|
||||
|
||||
// AddPermission to every entry,
|
||||
// NO MORE THAN 0777
|
||||
AddPermission os.FileMode
|
||||
|
||||
// Sync file after copy.
|
||||
// Useful in case when file must be on the disk
|
||||
// (in case crash happens, for example),
|
||||
// at the expense of some performance penalty
|
||||
Sync bool
|
||||
|
||||
// Preserve the atime and the mtime of the entries
|
||||
// On linux we can preserve only up to 1 millisecond accuracy
|
||||
PreserveTimes bool
|
||||
|
||||
// Preserve the uid and the gid of all entries.
|
||||
PreserveOwner bool
|
||||
|
||||
// The byte size of the buffer to use for copying files.
|
||||
// If zero, the internal default buffer of 32KB is used.
|
||||
// See https://golang.org/pkg/io/#CopyBuffer for more information.
|
||||
CopyBufferSize uint
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// For example...
|
||||
opt := Options{
|
||||
Skip: func(src string) (bool, error) {
|
||||
return strings.HasSuffix(src, ".git"), nil
|
||||
},
|
||||
}
|
||||
err := Copy("your/directory", "your/directory.copy", opt)
|
||||
```
|
||||
|
||||
# Issues
|
||||
|
||||
- https://github.com/otiai10/copy/issues
|
||||
|
||||
|
||||
## License
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fotiai10%2Fcopy?ref=badge_large)
|
243
vendor/github.com/otiai10/copy/copy.go
generated
vendored
Normal file
243
vendor/github.com/otiai10/copy/copy.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package copy
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// tmpPermissionForDirectory makes the destination directory writable,
|
||||
// so that stuff can be copied recursively even if any original directory is NOT writable.
|
||||
// See https://github.com/otiai10/copy/pull/9 for more information.
|
||||
tmpPermissionForDirectory = os.FileMode(0755)
|
||||
)
|
||||
|
||||
type timespec struct {
|
||||
Mtime time.Time
|
||||
Atime time.Time
|
||||
Ctime time.Time
|
||||
}
|
||||
|
||||
// Copy copies src to dest, doesn't matter if src is a directory or a file.
|
||||
func Copy(src, dest string, opt ...Options) error {
|
||||
info, err := os.Lstat(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return switchboard(src, dest, info, assure(src, dest, opt...))
|
||||
}
|
||||
|
||||
// switchboard switches proper copy functions regarding file type, etc...
|
||||
// If there would be anything else here, add a case to this switchboard.
|
||||
func switchboard(src, dest string, info os.FileInfo, opt Options) (err error) {
|
||||
switch {
|
||||
case info.Mode()&os.ModeSymlink != 0:
|
||||
err = onsymlink(src, dest, opt)
|
||||
case info.IsDir():
|
||||
err = dcopy(src, dest, info, opt)
|
||||
case info.Mode()&os.ModeNamedPipe != 0:
|
||||
err = pcopy(dest, info)
|
||||
default:
|
||||
err = fcopy(src, dest, info, opt)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// copyNextOrSkip decide if this src should be copied or not.
|
||||
// Because this "copy" could be called recursively,
|
||||
// "info" MUST be given here, NOT nil.
|
||||
func copyNextOrSkip(src, dest string, info os.FileInfo, opt Options) error {
|
||||
skip, err := opt.Skip(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skip {
|
||||
return nil
|
||||
}
|
||||
return switchboard(src, dest, info, opt)
|
||||
}
|
||||
|
||||
// fcopy is for just a file,
|
||||
// with considering existence of parent directory
|
||||
// and file permission.
|
||||
func fcopy(src, dest string, info os.FileInfo, opt Options) (err error) {
|
||||
|
||||
if err = os.MkdirAll(filepath.Dir(dest), os.ModePerm); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer fclose(f, &err)
|
||||
|
||||
if err = os.Chmod(f.Name(), info.Mode()|opt.AddPermission); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s, err := os.Open(src)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer fclose(s, &err)
|
||||
|
||||
var buf []byte = nil
|
||||
var w io.Writer = f
|
||||
// var r io.Reader = s
|
||||
if opt.CopyBufferSize != 0 {
|
||||
buf = make([]byte, opt.CopyBufferSize)
|
||||
// Disable using `ReadFrom` by io.CopyBuffer.
|
||||
// See https://github.com/otiai10/copy/pull/60#discussion_r627320811 for more details.
|
||||
w = struct{ io.Writer }{f}
|
||||
// r = struct{ io.Reader }{s}
|
||||
}
|
||||
if _, err = io.CopyBuffer(w, s, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opt.Sync {
|
||||
err = f.Sync()
|
||||
}
|
||||
|
||||
if opt.PreserveOwner {
|
||||
if err := preserveOwner(src, dest, info); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if opt.PreserveTimes {
|
||||
if err := preserveTimes(info, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// dcopy is for a directory,
|
||||
// with scanning contents inside the directory
|
||||
// and pass everything to "copy" recursively.
|
||||
func dcopy(srcdir, destdir string, info os.FileInfo, opt Options) (err error) {
|
||||
|
||||
_, err = os.Stat(destdir)
|
||||
if err == nil && opt.OnDirExists != nil && destdir != opt.intent.dest {
|
||||
switch opt.OnDirExists(srcdir, destdir) {
|
||||
case Replace:
|
||||
if err := os.RemoveAll(destdir); err != nil {
|
||||
return err
|
||||
}
|
||||
case Untouchable:
|
||||
return nil
|
||||
} // case "Merge" is default behaviour. Go through.
|
||||
} else if err != nil && !os.IsNotExist(err) {
|
||||
return err // Unwelcome error type...!
|
||||
}
|
||||
|
||||
originalMode := info.Mode()
|
||||
|
||||
// Make dest dir with 0755 so that everything writable.
|
||||
if err = os.MkdirAll(destdir, tmpPermissionForDirectory); err != nil {
|
||||
return
|
||||
}
|
||||
// Recover dir mode with original one.
|
||||
defer chmod(destdir, originalMode|opt.AddPermission, &err)
|
||||
|
||||
contents, err := ioutil.ReadDir(srcdir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, content := range contents {
|
||||
cs, cd := filepath.Join(srcdir, content.Name()), filepath.Join(destdir, content.Name())
|
||||
|
||||
if err = copyNextOrSkip(cs, cd, content, opt); err != nil {
|
||||
// If any error, exit immediately
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if opt.PreserveTimes {
|
||||
if err := preserveTimes(info, destdir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if opt.PreserveOwner {
|
||||
if err := preserveOwner(srcdir, destdir, info); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func onsymlink(src, dest string, opt Options) error {
|
||||
switch opt.OnSymlink(src) {
|
||||
case Shallow:
|
||||
return lcopy(src, dest)
|
||||
case Deep:
|
||||
orig, err := os.Readlink(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := os.Lstat(orig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return copyNextOrSkip(orig, dest, info, opt)
|
||||
case Skip:
|
||||
fallthrough
|
||||
default:
|
||||
return nil // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// lcopy is for a symlink,
|
||||
// with just creating a new symlink by replicating src symlink.
|
||||
func lcopy(src, dest string) error {
|
||||
src, err := os.Readlink(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Symlink(src, dest)
|
||||
}
|
||||
|
||||
// fclose ANYHOW closes file,
|
||||
// with asiging error raised during Close,
|
||||
// BUT respecting the error already reported.
|
||||
func fclose(f *os.File, reported *error) {
|
||||
if err := f.Close(); *reported == nil {
|
||||
*reported = err
|
||||
}
|
||||
}
|
||||
|
||||
// chmod ANYHOW changes file mode,
|
||||
// with asiging error raised during Chmod,
|
||||
// BUT respecting the error already reported.
|
||||
func chmod(dir string, mode os.FileMode, reported *error) {
|
||||
if err := os.Chmod(dir, mode); *reported == nil {
|
||||
*reported = err
|
||||
}
|
||||
}
|
||||
|
||||
// assure Options struct, should be called only once.
|
||||
// All optional values MUST NOT BE nil/zero after assured.
|
||||
func assure(src, dest string, opts ...Options) Options {
|
||||
defopt := getDefaultOptions(src, dest)
|
||||
if len(opts) == 0 {
|
||||
return defopt
|
||||
}
|
||||
if opts[0].OnSymlink == nil {
|
||||
opts[0].OnSymlink = defopt.OnSymlink
|
||||
}
|
||||
if opts[0].Skip == nil {
|
||||
opts[0].Skip = defopt.Skip
|
||||
}
|
||||
opts[0].intent.src = defopt.intent.src
|
||||
opts[0].intent.dest = defopt.intent.dest
|
||||
return opts[0]
|
||||
}
|
17
vendor/github.com/otiai10/copy/copy_namedpipes.go
generated
vendored
Normal file
17
vendor/github.com/otiai10/copy/copy_namedpipes.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// +build !windows,!plan9,!netbsd,!aix,!illumos,!solaris
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// pcopy is for just named pipes
|
||||
func pcopy(dest string, info os.FileInfo) error {
|
||||
if err := os.MkdirAll(filepath.Dir(dest), os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
return syscall.Mkfifo(dest, uint32(info.Mode()))
|
||||
}
|
14
vendor/github.com/otiai10/copy/copy_namedpipes_x.go
generated
vendored
Normal file
14
vendor/github.com/otiai10/copy/copy_namedpipes_x.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// +build windows plan9 netbsd aix illumos solaris
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// TODO: check plan9 netbsd aix illumos solaris in future
|
||||
|
||||
// pcopy is for just named pipes. Windows doesn't support them
|
||||
func pcopy(dest string, info os.FileInfo) error {
|
||||
return nil
|
||||
}
|
12
vendor/github.com/otiai10/copy/fileinfo.go
generated
vendored
Normal file
12
vendor/github.com/otiai10/copy/fileinfo.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package copy
|
||||
|
||||
// This is a cloned definition of os.FileInfo (go1.15) or fs.FileInfo (go1.16~)
|
||||
// A FileInfo describes a file and is returned by Stat.
|
||||
type fileInfo interface {
|
||||
// Name() string // base name of the file
|
||||
// Size() int64 // length in bytes for regular files; system-dependent for others
|
||||
// Mode() FileMode // file mode bits
|
||||
// ModTime() time.Time // modification time
|
||||
// IsDir() bool // abbreviation for Mode().IsDir()
|
||||
Sys() interface{} // underlying data source (can return nil)
|
||||
}
|
89
vendor/github.com/otiai10/copy/options.go
generated
vendored
Normal file
89
vendor/github.com/otiai10/copy/options.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
package copy
|
||||
|
||||
import "os"
|
||||
|
||||
// Options specifies optional actions on copying.
|
||||
type Options struct {
|
||||
|
||||
// OnSymlink can specify what to do on symlink
|
||||
OnSymlink func(src string) SymlinkAction
|
||||
|
||||
// OnDirExists can specify what to do when there is a directory already existing in destination.
|
||||
OnDirExists func(src, dest string) DirExistsAction
|
||||
|
||||
// Skip can specify which files should be skipped
|
||||
Skip func(src string) (bool, error)
|
||||
|
||||
// AddPermission to every entities,
|
||||
// NO MORE THAN 0777
|
||||
AddPermission os.FileMode
|
||||
|
||||
// Sync file after copy.
|
||||
// Useful in case when file must be on the disk
|
||||
// (in case crash happens, for example),
|
||||
// at the expense of some performance penalty
|
||||
Sync bool
|
||||
|
||||
// Preserve the atime and the mtime of the entries.
|
||||
// On linux we can preserve only up to 1 millisecond accuracy.
|
||||
PreserveTimes bool
|
||||
|
||||
// Preserve the uid and the gid of all entries.
|
||||
PreserveOwner bool
|
||||
|
||||
// The byte size of the buffer to use for copying files.
|
||||
// If zero, the internal default buffer of 32KB is used.
|
||||
// See https://golang.org/pkg/io/#CopyBuffer for more information.
|
||||
CopyBufferSize uint
|
||||
|
||||
intent struct {
|
||||
src string
|
||||
dest string
|
||||
}
|
||||
}
|
||||
|
||||
// SymlinkAction represents what to do on symlink.
|
||||
type SymlinkAction int
|
||||
|
||||
const (
|
||||
// Deep creates hard-copy of contents.
|
||||
Deep SymlinkAction = iota
|
||||
// Shallow creates new symlink to the dest of symlink.
|
||||
Shallow
|
||||
// Skip does nothing with symlink.
|
||||
Skip
|
||||
)
|
||||
|
||||
// DirExistsAction represents what to do on dest dir.
|
||||
type DirExistsAction int
|
||||
|
||||
const (
|
||||
// Merge preserves or overwrites existing files under the dir (default behavior).
|
||||
Merge DirExistsAction = iota
|
||||
// Replace deletes all contents under the dir and copy src files.
|
||||
Replace
|
||||
// Untouchable does nothing for the dir, and leaves it as it is.
|
||||
Untouchable
|
||||
)
|
||||
|
||||
// getDefaultOptions provides default options,
|
||||
// which would be modified by usage-side.
|
||||
func getDefaultOptions(src, dest string) Options {
|
||||
return Options{
|
||||
OnSymlink: func(string) SymlinkAction {
|
||||
return Shallow // Do shallow copy
|
||||
},
|
||||
OnDirExists: nil, // Default behavior is "Merge".
|
||||
Skip: func(string) (bool, error) {
|
||||
return false, nil // Don't skip
|
||||
},
|
||||
AddPermission: 0, // Add nothing
|
||||
Sync: false, // Do not sync
|
||||
PreserveTimes: false, // Do not preserve the modification time
|
||||
CopyBufferSize: 0, // Do not specify, use default bufsize (32*1024)
|
||||
intent: struct {
|
||||
src string
|
||||
dest string
|
||||
}{src, dest},
|
||||
}
|
||||
}
|
22
vendor/github.com/otiai10/copy/preserve_owner.go
generated
vendored
Normal file
22
vendor/github.com/otiai10/copy/preserve_owner.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
//+build !windows
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func preserveOwner(src, dest string, info fileInfo) (err error) {
|
||||
if info == nil {
|
||||
if info, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
if err := os.Chown(dest, int(stat.Uid), int(stat.Gid)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
7
vendor/github.com/otiai10/copy/preserve_owner_windows.go
generated
vendored
Normal file
7
vendor/github.com/otiai10/copy/preserve_owner_windows.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
//+build windows
|
||||
|
||||
package copy
|
||||
|
||||
func preserveOwner(src, dest string, info fileInfo) (err error) {
|
||||
return nil
|
||||
}
|
11
vendor/github.com/otiai10/copy/preserve_times.go
generated
vendored
Normal file
11
vendor/github.com/otiai10/copy/preserve_times.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
package copy
|
||||
|
||||
import "os"
|
||||
|
||||
func preserveTimes(srcinfo os.FileInfo, dest string) error {
|
||||
spec := getTimeSpec(srcinfo)
|
||||
if err := os.Chtimes(dest, spec.Atime, spec.Mtime); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
21
vendor/github.com/otiai10/copy/stat_times.go
generated
vendored
Normal file
21
vendor/github.com/otiai10/copy/stat_times.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// +build !windows,!darwin,!freebsd,!plan9,!netbsd
|
||||
|
||||
// TODO: add more runtimes
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getTimeSpec(info os.FileInfo) timespec {
|
||||
stat := info.Sys().(*syscall.Stat_t)
|
||||
times := timespec{
|
||||
Mtime: info.ModTime(),
|
||||
Atime: time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)),
|
||||
Ctime: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)),
|
||||
}
|
||||
return times
|
||||
}
|
19
vendor/github.com/otiai10/copy/stat_times_darwin.go
generated
vendored
Normal file
19
vendor/github.com/otiai10/copy/stat_times_darwin.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// +build darwin
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getTimeSpec(info os.FileInfo) timespec {
|
||||
stat := info.Sys().(*syscall.Stat_t)
|
||||
times := timespec{
|
||||
Mtime: info.ModTime(),
|
||||
Atime: time.Unix(stat.Atimespec.Sec, stat.Atimespec.Nsec),
|
||||
Ctime: time.Unix(stat.Ctimespec.Sec, stat.Ctimespec.Nsec),
|
||||
}
|
||||
return times
|
||||
}
|
19
vendor/github.com/otiai10/copy/stat_times_freebsd.go
generated
vendored
Normal file
19
vendor/github.com/otiai10/copy/stat_times_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// +build freebsd
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getTimeSpec(info os.FileInfo) timespec {
|
||||
stat := info.Sys().(*syscall.Stat_t)
|
||||
times := timespec{
|
||||
Mtime: info.ModTime(),
|
||||
Atime: time.Unix(int64(stat.Atimespec.Sec), int64(stat.Atimespec.Nsec)),
|
||||
Ctime: time.Unix(int64(stat.Ctimespec.Sec), int64(stat.Ctimespec.Nsec)),
|
||||
}
|
||||
return times
|
||||
}
|
18
vendor/github.com/otiai10/copy/stat_times_windows.go
generated
vendored
Normal file
18
vendor/github.com/otiai10/copy/stat_times_windows.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// +build windows
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getTimeSpec(info os.FileInfo) timespec {
|
||||
stat := info.Sys().(*syscall.Win32FileAttributeData)
|
||||
return timespec{
|
||||
Mtime: time.Unix(0, stat.LastWriteTime.Nanoseconds()),
|
||||
Atime: time.Unix(0, stat.LastAccessTime.Nanoseconds()),
|
||||
Ctime: time.Unix(0, stat.CreationTime.Nanoseconds()),
|
||||
}
|
||||
}
|
17
vendor/github.com/otiai10/copy/stat_times_x.go
generated
vendored
Normal file
17
vendor/github.com/otiai10/copy/stat_times_x.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// +build plan9 netbsd
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// TODO: check plan9 netbsd in future
|
||||
func getTimeSpec(info os.FileInfo) timespec {
|
||||
times := timespec{
|
||||
Mtime: info.ModTime(),
|
||||
Atime: info.ModTime(),
|
||||
Ctime: info.ModTime(),
|
||||
}
|
||||
return times
|
||||
}
|
17
vendor/github.com/otiai10/copy/test_setup.go
generated
vendored
Normal file
17
vendor/github.com/otiai10/copy/test_setup.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// +build !windows,!plan9,!netbsd,!aix,!illumos,!solaris
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setup(m *testing.M) {
|
||||
os.MkdirAll("test/data.copy", os.ModePerm)
|
||||
os.Symlink("test/data/case01", "test/data/case03/case01")
|
||||
os.Chmod("test/data/case07/dir_0555", 0555)
|
||||
os.Chmod("test/data/case07/file_0444", 0444)
|
||||
syscall.Mkfifo("test/data/case11/foo/bar", 0555)
|
||||
}
|
15
vendor/github.com/otiai10/copy/test_setup_x.go
generated
vendored
Normal file
15
vendor/github.com/otiai10/copy/test_setup_x.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// +build windows plan9 netbsd aix illumos solaris
|
||||
|
||||
package copy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setup(m *testing.M) {
|
||||
os.MkdirAll("test/data.copy", os.ModePerm)
|
||||
os.Symlink("test/data/case01", "test/data/case03/case01")
|
||||
os.Chmod("test/data/case07/dir_0555", 0555)
|
||||
os.Chmod("test/data/case07/file_0444", 0444)
|
||||
}
|
Reference in New Issue
Block a user