1package fileutil 2 3import ( 4 "io" 5 "os" 6 "path/filepath" 7 8 "github.com/pkg/errors" 9) 10 11// Copy copies 'from' to 'to'. 12// If directries are not exist, Copy creates these. 13func Copy(to, from string) error { 14 toDir := filepath.Dir(to) 15 if _, err := os.Stat(toDir); os.IsNotExist(err) { 16 if err := os.MkdirAll(toDir, 0755); err != nil { 17 return errors.Wrap(err, "failed to create destination directories") 18 } 19 } 20 21 ff, err := os.Open(from) 22 if err != nil { 23 return errors.Wrapf(err, "failed to open %s", from) 24 } 25 defer ff.Close() 26 fi, err := ff.Stat() 27 if err != nil { 28 return errors.Wrapf(err, "failed to get file info from %s", from) 29 } 30 31 tf, err := os.Create(to) 32 if err != nil { 33 return errors.Wrapf(err, "failed to create %s", to) 34 } 35 defer tf.Close() 36 if err := tf.Chmod(fi.Mode()); err != nil { 37 return errors.Wrap(err, "failed to chmod cached binary") 38 } 39 40 _, err = io.Copy(tf, ff) 41 if err != nil { 42 return errors.Wrapf(err, "failed to copy from %s to %s", from, to) 43 } 44 45 return nil 46} 47