summaryrefslogtreecommitdiff
path: root/vendor/github.com/otiai10
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-10-25 00:47:47 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-10-25 00:47:47 +0200
commitc6cc0108ca7738023b45e0eeac0fa2390532dd93 (patch)
tree36890e6cd3091bbab8efbe686cc56f467f645bfd /vendor/github.com/otiai10
parent0130404a1dc663d4aa68d780c9bcb23a4243e68d (diff)
downloadjbmafp-master.tar.gz
Added vendor lock on depsHEADmaster
Diffstat (limited to 'vendor/github.com/otiai10')
-rw-r--r--vendor/github.com/otiai10/copy/.gitignore9
-rw-r--r--vendor/github.com/otiai10/copy/LICENSE21
-rw-r--r--vendor/github.com/otiai10/copy/README.md108
-rw-r--r--vendor/github.com/otiai10/copy/copy.go284
-rw-r--r--vendor/github.com/otiai10/copy/copy_namedpipes.go18
-rw-r--r--vendor/github.com/otiai10/copy/copy_namedpipes_x.go15
-rw-r--r--vendor/github.com/otiai10/copy/fileinfo_go1.15.go17
-rw-r--r--vendor/github.com/otiai10/copy/fileinfo_go1.16.go17
-rw-r--r--vendor/github.com/otiai10/copy/options.go143
-rw-r--r--vendor/github.com/otiai10/copy/permission_control.go48
-rw-r--r--vendor/github.com/otiai10/copy/preserve_ltimes.go20
-rw-r--r--vendor/github.com/otiai10/copy/preserve_ltimes_x.go8
-rw-r--r--vendor/github.com/otiai10/copy/preserve_owner.go23
-rw-r--r--vendor/github.com/otiai10/copy/preserve_owner_x.go8
-rw-r--r--vendor/github.com/otiai10/copy/preserve_times.go11
-rw-r--r--vendor/github.com/otiai10/copy/stat_times.go22
-rw-r--r--vendor/github.com/otiai10/copy/stat_times_darwin.go20
-rw-r--r--vendor/github.com/otiai10/copy/stat_times_freebsd.go20
-rw-r--r--vendor/github.com/otiai10/copy/stat_times_js.go20
-rw-r--r--vendor/github.com/otiai10/copy/stat_times_windows.go19
-rw-r--r--vendor/github.com/otiai10/copy/stat_times_x.go18
-rw-r--r--vendor/github.com/otiai10/copy/test/data/case18/assets/README.md1
-rw-r--r--vendor/github.com/otiai10/copy/test_setup.go20
-rw-r--r--vendor/github.com/otiai10/copy/test_setup_x.go17
24 files changed, 907 insertions, 0 deletions
diff --git a/vendor/github.com/otiai10/copy/.gitignore b/vendor/github.com/otiai10/copy/.gitignore
new file mode 100644
index 0000000..a793485
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/.gitignore
@@ -0,0 +1,9 @@
+test/data.copy
+test/owned-by-root
+coverage.txt
+vendor
+.vagrant
+.idea/
+
+# Test Specific
+test/data/case16/large.file
diff --git a/vendor/github.com/otiai10/copy/LICENSE b/vendor/github.com/otiai10/copy/LICENSE
new file mode 100644
index 0000000..1f0cc5d
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/LICENSE
@@ -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.
diff --git a/vendor/github.com/otiai10/copy/README.md b/vendor/github.com/otiai10/copy/README.md
new file mode 100644
index 0000000..1cc8fc8
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/README.md
@@ -0,0 +1,108 @@
+# copy
+
+[![Go Reference](https://pkg.go.dev/badge/github.com/otiai10/copy.svg)](https://pkg.go.dev/github.com/otiai10/copy)
+[![Actions Status](https://github.com/otiai10/copy/workflows/Go/badge.svg)](https://github.com/otiai10/copy/actions)
+[![codecov](https://codecov.io/gh/otiai10/copy/branch/main/graph/badge.svg)](https://codecov.io/gh/otiai10/copy)
+[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/otiai10/copy/blob/main/LICENSE)
+[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fotiai10%2Fcopy.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fotiai10%2Fcopy?ref=badge_shield)
+[![CodeQL](https://github.com/otiai10/copy/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/codeql-analysis.yml)
+[![Go Report Card](https://goreportcard.com/badge/github.com/otiai10/copy)](https://goreportcard.com/report/github.com/otiai10/copy)
+[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/otiai10/copy?sort=semver)](https://pkg.go.dev/github.com/otiai10/copy)
+[![Docker Test](https://github.com/otiai10/copy/actions/workflows/docker-test.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/docker-test.yml)
+[![Vagrant Test](https://github.com/otiai10/copy/actions/workflows/vagrant-test.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/vagrant-test.yml)
+
+`copy` copies directories recursively.
+
+# Example Usage
+
+```go
+package main
+
+import (
+ "fmt"
+ cp "github.com/otiai10/copy"
+)
+
+func main() {
+ err := cp.Copy("your/src", "your/dest")
+ fmt.Println(err) // nil
+}
+```
+
+# 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
+
+ // OnError can let users decide how to handle errors (e.g., you can suppress specific error).
+ OnError func(src, dest, string, err error) error
+
+ // Skip can specify which files should be skipped
+ Skip func(srcinfo os.FileInfo, src, dest string) (bool, error)
+
+ // PermissionControl can control permission of
+ // every entry.
+ // When you want to add permission 0222, do like
+ //
+ // PermissionControl = AddPermission(0222)
+ //
+ // or if you even don't want to touch permission,
+ //
+ // PermissionControl = DoNothing
+ //
+ // By default, PermissionControl = PreservePermission
+ PermissionControl PermissionControlFunc
+
+ // 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
+
+ // If you want to add some limitation on reading src file,
+ // you can wrap the src and provide new reader,
+ // such as `RateLimitReader` in the test case.
+ WrapReader func(src io.Reader) io.Reader
+
+ // If given, copy.Copy refers to this fs.FS instead of the OS filesystem.
+ // e.g., You can use embed.FS to copy files from embedded filesystem.
+ FS fs.FS
+}
+```
+
+```go
+// For example...
+opt := Options{
+ Skip: func(info os.FileInfo, src, dest 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
+[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fotiai10%2Fcopy.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fotiai10%2Fcopy?ref=badge_large) \ No newline at end of file
diff --git a/vendor/github.com/otiai10/copy/copy.go b/vendor/github.com/otiai10/copy/copy.go
new file mode 100644
index 0000000..085db78
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/copy.go
@@ -0,0 +1,284 @@
+package copy
+
+import (
+ "io"
+ "io/fs"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+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, opts ...Options) error {
+ opt := assureOptions(src, dest, opts...)
+ if opt.FS != nil {
+ info, err := fs.Stat(opt.FS, src)
+ if err != nil {
+ return onError(src, dest, err, opt)
+ }
+ return switchboard(src, dest, info, opt)
+ }
+ info, err := os.Lstat(src)
+ if err != nil {
+ return onError(src, dest, err, opt)
+ }
+ return switchboard(src, dest, info, 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) {
+ if info.Mode()&os.ModeDevice != 0 && !opt.Specials {
+ return onError(src, dest, err, opt)
+ }
+
+ 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 onError(src, dest, err, opt)
+}
+
+// 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 {
+ if opt.Skip != nil {
+ skip, err := opt.Skip(info, src, dest)
+ 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) {
+
+ var readcloser io.ReadCloser
+ if opt.FS != nil {
+ readcloser, err = opt.FS.Open(src)
+ } else {
+ readcloser, err = os.Open(src)
+ }
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return
+ }
+ defer fclose(readcloser, &err)
+
+ 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)
+
+ chmodfunc, err := opt.PermissionControl(info, dest)
+ if err != nil {
+ return err
+ }
+ chmodfunc(&err)
+
+ var buf []byte = nil
+ var w io.Writer = f
+ var r io.Reader = readcloser
+
+ if opt.WrapReader != nil {
+ r = opt.WrapReader(r)
+ }
+
+ 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, r, 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) {
+ if skip, err := onDirExists(opt, srcdir, destdir); err != nil {
+ return err
+ } else if skip {
+ return nil
+ }
+
+ // Make dest dir with 0755 so that everything writable.
+ chmodfunc, err := opt.PermissionControl(info, destdir)
+ if err != nil {
+ return err
+ }
+ defer chmodfunc(&err)
+
+ var contents []os.FileInfo
+ if opt.FS != nil {
+ entries, err := fs.ReadDir(opt.FS, srcdir)
+ if err != nil {
+ return err
+ }
+ for _, e := range entries {
+ info, err := e.Info()
+ if err != nil {
+ return err
+ }
+ contents = append(contents, info)
+ }
+ } else {
+ contents, err = ioutil.ReadDir(srcdir)
+ }
+
+ if err != nil {
+ if os.IsNotExist(err) {
+ return 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 onDirExists(opt Options, srcdir, destdir string) (bool, 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 false, err
+ }
+ case Untouchable:
+ return true, nil
+ } // case "Merge" is default behaviour. Go through.
+ } else if err != nil && !os.IsNotExist(err) {
+ return true, err // Unwelcome error type...!
+ }
+ return false, nil
+}
+
+func onsymlink(src, dest string, opt Options) error {
+ switch opt.OnSymlink(src) {
+ case Shallow:
+ if err := lcopy(src, dest); err != nil {
+ return err
+ }
+ if opt.PreserveTimes {
+ return preserveLtimes(src, dest)
+ }
+ return nil
+ 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 {
+ if os.IsNotExist(err) {
+ return 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 io.Closer, reported *error) {
+ if err := f.Close(); *reported == nil {
+ *reported = err
+ }
+}
+
+// onError lets caller to handle errors
+// occured when copying a file.
+func onError(src, dest string, err error, opt Options) error {
+ if opt.OnError == nil {
+ return err
+ }
+
+ return opt.OnError(src, dest, err)
+}
diff --git a/vendor/github.com/otiai10/copy/copy_namedpipes.go b/vendor/github.com/otiai10/copy/copy_namedpipes.go
new file mode 100644
index 0000000..615ddcd
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/copy_namedpipes.go
@@ -0,0 +1,18 @@
+//go:build !windows && !plan9 && !netbsd && !aix && !illumos && !solaris && !js
+// +build !windows,!plan9,!netbsd,!aix,!illumos,!solaris,!js
+
+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()))
+}
diff --git a/vendor/github.com/otiai10/copy/copy_namedpipes_x.go b/vendor/github.com/otiai10/copy/copy_namedpipes_x.go
new file mode 100644
index 0000000..38dd9dc
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/copy_namedpipes_x.go
@@ -0,0 +1,15 @@
+//go:build windows || plan9 || netbsd || aix || illumos || solaris || js
+// +build windows plan9 netbsd aix illumos solaris js
+
+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
+}
diff --git a/vendor/github.com/otiai10/copy/fileinfo_go1.15.go b/vendor/github.com/otiai10/copy/fileinfo_go1.15.go
new file mode 100644
index 0000000..c0708ea
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/fileinfo_go1.15.go
@@ -0,0 +1,17 @@
+//go:build !go1.16
+// +build !go1.16
+
+package copy
+
+import "os"
+
+// 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() os.FileMode // file mode bits
+ // ModTime() time.Time // modification time
+ IsDir() bool // abbreviation for Mode().IsDir()
+ Sys() interface{} // underlying data source (can return nil)
+}
diff --git a/vendor/github.com/otiai10/copy/fileinfo_go1.16.go b/vendor/github.com/otiai10/copy/fileinfo_go1.16.go
new file mode 100644
index 0000000..01b3fd2
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/fileinfo_go1.16.go
@@ -0,0 +1,17 @@
+//go:build go1.16
+// +build go1.16
+
+package copy
+
+import "io/fs"
+
+// 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() fs.FileMode // file mode bits
+ // ModTime() time.Time // modification time
+ IsDir() bool // abbreviation for Mode().IsDir()
+ Sys() interface{} // underlying data source (can return nil)
+}
diff --git a/vendor/github.com/otiai10/copy/options.go b/vendor/github.com/otiai10/copy/options.go
new file mode 100644
index 0000000..1b4e508
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/options.go
@@ -0,0 +1,143 @@
+package copy
+
+import (
+ "io"
+ "io/fs"
+ "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
+
+ // OnErr lets called decide whether or not to continue on particular copy error.
+ OnError func(src, dest string, err error) error
+
+ // Skip can specify which files should be skipped
+ Skip func(srcinfo os.FileInfo, src, dest string) (bool, error)
+
+ // Specials includes special files to be copied. default false.
+ Specials bool
+
+ // AddPermission to every entities,
+ // NO MORE THAN 0777
+ // @OBSOLETE
+ // Use `PermissionControl = AddPermission(perm)` instead
+ AddPermission os.FileMode
+
+ // PermissionControl can preserve or even add permission to
+ // every entries, for example
+ //
+ // opt.PermissionControl = AddPermission(0222)
+ //
+ // See permission_control.go for more detail.
+ PermissionControl PermissionControlFunc
+
+ // 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
+
+ // If you want to add some limitation on reading src file,
+ // you can wrap the src and provide new reader,
+ // such as `RateLimitReader` in the test case.
+ WrapReader func(src io.Reader) io.Reader
+
+ // If given, copy.Copy refers to this fs.FS instead of the OS filesystem.
+ // e.g., You can use embed.FS to copy files from embedded filesystem.
+ FS fs.FS
+
+ 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".
+ OnError: nil, // Default is "accept error"
+ Skip: nil, // Do not skip anything
+ AddPermission: 0, // Add nothing
+ PermissionControl: PerservePermission, // Just preserve permission
+ Sync: false, // Do not sync
+ Specials: false, // Do not copy special files
+ PreserveTimes: false, // Do not preserve the modification time
+ CopyBufferSize: 0, // Do not specify, use default bufsize (32*1024)
+ WrapReader: nil, // Do not wrap src files, use them as they are.
+ intent: struct {
+ src string
+ dest string
+ }{src, dest},
+ }
+}
+
+// assureOptions struct, should be called only once.
+// All optional values MUST NOT BE nil/zero after assured.
+func assureOptions(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
+ }
+ if opts[0].AddPermission > 0 {
+ opts[0].PermissionControl = AddPermission(opts[0].AddPermission)
+ } else if opts[0].PermissionControl == nil {
+ opts[0].PermissionControl = PerservePermission
+ }
+ opts[0].intent.src = defopt.intent.src
+ opts[0].intent.dest = defopt.intent.dest
+ return opts[0]
+}
diff --git a/vendor/github.com/otiai10/copy/permission_control.go b/vendor/github.com/otiai10/copy/permission_control.go
new file mode 100644
index 0000000..97ae12d
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/permission_control.go
@@ -0,0 +1,48 @@
+package copy
+
+import (
+ "os"
+)
+
+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 PermissionControlFunc func(srcinfo fileInfo, dest string) (chmodfunc func(*error), err error)
+
+var (
+ AddPermission = func(perm os.FileMode) PermissionControlFunc {
+ return func(srcinfo fileInfo, dest string) (func(*error), error) {
+ orig := srcinfo.Mode()
+ if srcinfo.IsDir() {
+ if err := os.MkdirAll(dest, tmpPermissionForDirectory); err != nil {
+ return func(*error) {}, err
+ }
+ }
+ return func(err *error) {
+ chmod(dest, orig|perm, err)
+ }, nil
+ }
+ }
+ PerservePermission PermissionControlFunc = AddPermission(0)
+ DoNothing PermissionControlFunc = func(srcinfo fileInfo, dest string) (func(*error), error) {
+ if srcinfo.IsDir() {
+ if err := os.MkdirAll(dest, srcinfo.Mode()); err != nil {
+ return func(*error) {}, err
+ }
+ }
+ return func(*error) {}, nil
+ }
+)
+
+// 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
+ }
+}
diff --git a/vendor/github.com/otiai10/copy/preserve_ltimes.go b/vendor/github.com/otiai10/copy/preserve_ltimes.go
new file mode 100644
index 0000000..cc006d3
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/preserve_ltimes.go
@@ -0,0 +1,20 @@
+//go:build !windows && !plan9 && !js
+// +build !windows,!plan9,!js
+
+package copy
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func preserveLtimes(src, dest string) error {
+ info := new(unix.Stat_t)
+ if err := unix.Lstat(src, info); err != nil {
+ return err
+ }
+
+ return unix.Lutimes(dest, []unix.Timeval{
+ unix.NsecToTimeval(info.Atim.Nano()),
+ unix.NsecToTimeval(info.Mtim.Nano()),
+ })
+}
diff --git a/vendor/github.com/otiai10/copy/preserve_ltimes_x.go b/vendor/github.com/otiai10/copy/preserve_ltimes_x.go
new file mode 100644
index 0000000..02aec40
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/preserve_ltimes_x.go
@@ -0,0 +1,8 @@
+//go:build windows || js || plan9
+// +build windows js plan9
+
+package copy
+
+func preserveLtimes(src, dest string) error {
+ return nil // Unsupported
+}
diff --git a/vendor/github.com/otiai10/copy/preserve_owner.go b/vendor/github.com/otiai10/copy/preserve_owner.go
new file mode 100644
index 0000000..13ec4f5
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/preserve_owner.go
@@ -0,0 +1,23 @@
+//go:build !windows && !plan9
+// +build !windows,!plan9
+
+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
+}
diff --git a/vendor/github.com/otiai10/copy/preserve_owner_x.go b/vendor/github.com/otiai10/copy/preserve_owner_x.go
new file mode 100644
index 0000000..9d82574
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/preserve_owner_x.go
@@ -0,0 +1,8 @@
+//go:build windows || plan9
+// +build windows plan9
+
+package copy
+
+func preserveOwner(src, dest string, info fileInfo) (err error) {
+ return nil
+}
diff --git a/vendor/github.com/otiai10/copy/preserve_times.go b/vendor/github.com/otiai10/copy/preserve_times.go
new file mode 100644
index 0000000..d89b128
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/preserve_times.go
@@ -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
+}
diff --git a/vendor/github.com/otiai10/copy/stat_times.go b/vendor/github.com/otiai10/copy/stat_times.go
new file mode 100644
index 0000000..75f45f6
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/stat_times.go
@@ -0,0 +1,22 @@
+//go:build !windows && !darwin && !freebsd && !plan9 && !netbsd && !js
+// +build !windows,!darwin,!freebsd,!plan9,!netbsd,!js
+
+// 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
+}
diff --git a/vendor/github.com/otiai10/copy/stat_times_darwin.go b/vendor/github.com/otiai10/copy/stat_times_darwin.go
new file mode 100644
index 0000000..d4c23d8
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/stat_times_darwin.go
@@ -0,0 +1,20 @@
+//go:build darwin
+// +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
+}
diff --git a/vendor/github.com/otiai10/copy/stat_times_freebsd.go b/vendor/github.com/otiai10/copy/stat_times_freebsd.go
new file mode 100644
index 0000000..5309334
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/stat_times_freebsd.go
@@ -0,0 +1,20 @@
+//go:build freebsd
+// +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
+}
diff --git a/vendor/github.com/otiai10/copy/stat_times_js.go b/vendor/github.com/otiai10/copy/stat_times_js.go
new file mode 100644
index 0000000..c645771
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/stat_times_js.go
@@ -0,0 +1,20 @@
+//go:build js
+// +build js
+
+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.Atime), int64(stat.AtimeNsec)),
+ Ctime: time.Unix(int64(stat.Ctime), int64(stat.CtimeNsec)),
+ }
+ return times
+}
diff --git a/vendor/github.com/otiai10/copy/stat_times_windows.go b/vendor/github.com/otiai10/copy/stat_times_windows.go
new file mode 100644
index 0000000..d6a84a7
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/stat_times_windows.go
@@ -0,0 +1,19 @@
+//go:build windows
+// +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()),
+ }
+}
diff --git a/vendor/github.com/otiai10/copy/stat_times_x.go b/vendor/github.com/otiai10/copy/stat_times_x.go
new file mode 100644
index 0000000..886ddd3
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/stat_times_x.go
@@ -0,0 +1,18 @@
+//go:build plan9 || netbsd
+// +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
+}
diff --git a/vendor/github.com/otiai10/copy/test/data/case18/assets/README.md b/vendor/github.com/otiai10/copy/test/data/case18/assets/README.md
new file mode 100644
index 0000000..5570c7f
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/test/data/case18/assets/README.md
@@ -0,0 +1 @@
+# Hello \ No newline at end of file
diff --git a/vendor/github.com/otiai10/copy/test_setup.go b/vendor/github.com/otiai10/copy/test_setup.go
new file mode 100644
index 0000000..64a5292
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/test_setup.go
@@ -0,0 +1,20 @@
+//go:build !windows && !plan9 && !netbsd && !aix && !illumos && !solaris && !js
+// +build !windows,!plan9,!netbsd,!aix,!illumos,!solaris,!js
+
+package copy
+
+import (
+ "os"
+ "syscall"
+ "testing"
+)
+
+func setup(m *testing.M) {
+ os.RemoveAll("test/data.copy")
+ os.MkdirAll("test/data.copy", os.ModePerm)
+ os.Symlink("test/data/case01", "test/data/case03/case01")
+ os.Chmod("test/data/case07/dir_0555", 0o555)
+ os.Chmod("test/data/case07/file_0444", 0o444)
+ syscall.Mkfifo("test/data/case11/foo/bar", 0o555)
+ Copy("test/data/case18/assets", "test/data/case18/assets.backup")
+}
diff --git a/vendor/github.com/otiai10/copy/test_setup_x.go b/vendor/github.com/otiai10/copy/test_setup_x.go
new file mode 100644
index 0000000..4c35b14
--- /dev/null
+++ b/vendor/github.com/otiai10/copy/test_setup_x.go
@@ -0,0 +1,17 @@
+//go:build windows || plan9 || netbsd || aix || illumos || solaris || js
+// +build windows plan9 netbsd aix illumos solaris js
+
+package copy
+
+import (
+ "os"
+ "testing"
+)
+
+func setup(m *testing.M) {
+ os.RemoveAll("test/data.copy")
+ 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)
+}