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