-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtree_copy.go
99 lines (78 loc) · 2.28 KB
/
tree_copy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2017-2019 Vlad Didenko. All rights reserved.
// See the included LICENSE.md file for licensing information
package fst // import "go.didenko.com/fst"
import (
"fmt"
"io"
"os"
"path/filepath"
)
// TreeCopy duplicates redular files and directories from
// inside the source directory into an existing destination
// directory.
func TreeCopy(f Fatalfable, src, dst string) {
srcClean := filepath.Clean(src)
srcLen := len(srcClean)
dirs := make([]*Node, 0)
err := filepath.Walk(
srcClean,
func(fn string, fi os.FileInfo, er error) error {
if er != nil || len(fn) <= srcLen {
return er
}
dest := filepath.Join(dst, fn[srcLen:])
if fi.Mode().IsRegular() {
srcf, err := os.Open(fn)
if err != nil {
return fmt.Errorf("Opening the sorce file %q: %s", fn, err)
}
dstf, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("Opening the dest file %q: %s", dest, err)
}
_, err = io.Copy(dstf, srcf)
if err != nil {
return fmt.Errorf("Copying %q to %q: %s", fn, dest, err)
}
err = srcf.Close()
if err != nil {
return fmt.Errorf("Closing the sorce file %q: %s", fn, err)
}
err = dstf.Close()
if err != nil {
return fmt.Errorf("Closing the dest file %q: %s", dest, err)
}
err = os.Chmod(dest, fi.Mode())
if err != nil {
return fmt.Errorf("Setting permissions on %q: %s", dest, err)
}
destMT := fi.ModTime()
err = os.Chtimes(dest, destMT, destMT)
if err != nil {
return fmt.Errorf("Setting timestamp %s on %q: %s", destMT, dest, err)
}
return nil
}
if fi.Mode().IsDir() {
dirs = append(dirs, &Node{fi.Mode().Perm(), fi.ModTime(), dest, ""})
err := os.Mkdir(dest, 0700)
if err != nil {
return fmt.Errorf("Creating dir %q: %s", dest, err)
}
}
return nil
})
if err != nil {
f.Fatalf("Copying tree from %q to %q: %s", src, dst, err)
}
for i := len(dirs) - 1; i >= 0; i-- {
err := os.Chmod(dirs[i].name, dirs[i].perm)
if err != nil {
f.Fatalf("Setting permissions on %q to %o: %s", dirs[i].name, dirs[i].perm, err)
}
err = os.Chtimes(dirs[i].name, dirs[i].time, dirs[i].time)
if err != nil {
f.Fatalf("Setting timestamp %s on %q: %s", dirs[i].time, dirs[i].name, err)
}
}
}