github.com/wtfutil/wtf@v0.43.0/cfg/copy.go (about) 1 // Copied verbatim from: 2 // 3 // https://github.com/otiai10/copy/blob/master/copy.go 4 5 package cfg 6 7 import ( 8 "io" 9 "os" 10 "path/filepath" 11 ) 12 13 // Copy copies src to dest, doesn't matter if src is a directory or a file 14 func Copy(src, dest string) error { 15 info, err := os.Stat(src) 16 if err != nil { 17 return err 18 } 19 return locationCopy(src, dest, info) 20 } 21 22 // "info" must be given here, NOT nil. 23 func locationCopy(src, dest string, info os.FileInfo) error { 24 if info.IsDir() { 25 return directoryCopy(src, dest, info) 26 } 27 return fileCopy(src, dest, info) 28 } 29 30 func fileCopy(src, dest string, info os.FileInfo) error { 31 32 f, err := os.Create(dest) 33 if err != nil { 34 return err 35 } 36 defer func() { _ = f.Close() }() 37 38 if err = os.Chmod(f.Name(), info.Mode()); err != nil { 39 return err 40 } 41 42 s, err := os.Open(filepath.Clean(src)) 43 if err != nil { 44 return err 45 } 46 defer func() { _ = f.Close() }() 47 48 _, err = io.Copy(f, s) 49 return err 50 } 51 52 func directoryCopy(src, dest string, info os.FileInfo) error { 53 54 if err := os.MkdirAll(dest, info.Mode()); err != nil { 55 return err 56 } 57 58 entries, err := os.ReadDir(src) 59 if err != nil { 60 return err 61 } 62 63 for _, entry := range entries { 64 info, err := entry.Info() 65 if err != nil { 66 continue 67 } 68 69 if err := locationCopy( 70 filepath.Join(src, info.Name()), 71 filepath.Join(dest, info.Name()), 72 info, 73 ); err != nil { 74 return err 75 } 76 } 77 78 return nil 79 }