1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
// Copyright 2024 Bjørn Erik Pedersen
// SPDX-License-Identifier: MIT
package filehelpers
import (
"fmt"
"io"
"os"
"path/filepath"
)
// CopyFile copies a file.
func CopyFile(from, to string) error {
sf, err := os.Open(from)
if err != nil {
return err
}
defer sf.Close()
df, err := os.Create(to)
if err != nil {
return err
}
defer df.Close()
_, err = io.Copy(df, sf)
if err != nil {
return err
}
si, err := os.Stat(from)
if err == nil {
err = os.Chmod(to, si.Mode())
if err != nil {
return err
}
}
return nil
}
// CopyDir copies a directory. Any directory or file matching the filter will be copied.
func CopyDir(from, to string, filter func(filename string) bool) error {
fi, err := os.Stat(from)
if err != nil {
return err
}
if !fi.IsDir() {
return fmt.Errorf("%q is not a directory", from)
}
err = os.MkdirAll(to, 0o777) // before umask
if err != nil {
return err
}
entries, err := os.ReadDir(from)
if err != nil {
return err
}
if filter == nil {
filter = func(filename string) bool {
return true
}
}
for _, entry := range entries {
fromFilename := filepath.Join(from, entry.Name())
toFilename := filepath.Join(to, entry.Name())
if !filter(fromFilename) {
continue
}
if entry.IsDir() {
if err := CopyDir(fromFilename, toFilename, filter); err != nil {
return err
}
} else {
if err := CopyFile(fromFilename, toFilename); err != nil {
return err
}
}
}
return nil
}
|