copyFile copies a file from src to dst, ensuring the containing directory exists. The permission bits are copied as well. If dst already exists and the contents are identical to src the modification time is not updated.
(src, dst string, perm os.FileMode)
| 754 | // exists. The permission bits are copied as well. If dst already exists and |
| 755 | // the contents are identical to src the modification time is not updated. |
| 756 | func copyFile(src, dst string, perm os.FileMode) error { |
| 757 | in, err := os.ReadFile(src) |
| 758 | if err != nil { |
| 759 | return err |
| 760 | } |
| 761 | |
| 762 | out, err := os.ReadFile(dst) |
| 763 | if err != nil { |
| 764 | // The destination probably doesn't exist, we should create |
| 765 | // it. |
| 766 | goto copy |
| 767 | } |
| 768 | |
| 769 | if bytes.Equal(in, out) { |
| 770 | // The permission bits may have changed without the contents |
| 771 | // changing so we always mirror them. |
| 772 | os.Chmod(dst, perm) |
| 773 | return nil |
| 774 | } |
| 775 | |
| 776 | copy: |
| 777 | os.MkdirAll(filepath.Dir(dst), 0o777) |
| 778 | if err := os.WriteFile(dst, in, perm); err != nil { |
| 779 | return err |
| 780 | } |
| 781 | |
| 782 | return nil |
| 783 | } |
| 784 | |
| 785 | func listFiles(dir string) []string { |
| 786 | var res []string |