copy.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package utils
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. )
  8. // Copy copies src to dest, doesn't matter if src is a directory or a file
  9. func Copy(src, dest string) error {
  10. src = ExpandHomeDir(filepath.Clean(src))
  11. dest = ExpandHomeDir(filepath.Clean(dest))
  12. info, err := os.Stat(src)
  13. if err != nil {
  14. return err
  15. }
  16. return copy(src, dest, info)
  17. }
  18. // "info" must be given here, NOT nil.
  19. func copy(src, dest string, info os.FileInfo) error {
  20. if info.IsDir() {
  21. return dcopy(src, dest, info)
  22. }
  23. return fcopy(src, dest, info)
  24. }
  25. func fcopy(src, dest string, info os.FileInfo) error {
  26. f, err := os.Create(dest)
  27. if err != nil {
  28. return err
  29. }
  30. defer f.Close()
  31. if err = os.Chmod(f.Name(), info.Mode()); err != nil {
  32. return err
  33. }
  34. s, err := os.Open(src)
  35. if err != nil {
  36. return err
  37. }
  38. defer s.Close()
  39. _, err = io.Copy(f, s)
  40. return err
  41. }
  42. func dcopy(src, dest string, info os.FileInfo) error {
  43. if err := os.MkdirAll(dest, info.Mode()); err != nil {
  44. return err
  45. }
  46. infos, err := ioutil.ReadDir(src)
  47. if err != nil {
  48. return err
  49. }
  50. for _, info := range infos {
  51. if err := copy(
  52. filepath.Join(src, info.Name()),
  53. filepath.Join(dest, info.Name()),
  54. info,
  55. ); err != nil {
  56. return err
  57. }
  58. }
  59. return nil
  60. }