-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdir.go
73 lines (58 loc) · 1.34 KB
/
dir.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
package textree
import (
"fmt"
"os"
"path/filepath"
"strings"
)
const (
pathIDSeparator = "__"
)
// TreeFromDir generates a tree representing given directory structure
func TreeFromDir(dir string) (*Node, error) {
absPath, err := filepath.Abs(dir)
if err != nil {
return nil, err
}
pathStat, err := os.Stat(absPath)
if err != nil {
return nil, err
}
if !pathStat.IsDir() {
return nil, fmt.Errorf("path must be a valid directory, but %s isn't", absPath)
}
dirPathLen := len(absPath)
// Manually creating root directory
root := NewNode(dir)
s := map[string]*Node{
"": root,
}
walkErr := filepath.Walk(absPath, func(path string, f os.FileInfo, err error) error {
// skipping root as it has already been defined
if len(path) == dirPathLen {
return nil
}
// removing base directory path + path separator
rel := path[dirPathLen+1:]
// splitting path
parts := strings.Split(rel, string(os.PathSeparator))
parent := root
currentPath := ""
for idx, x := range parts {
if idx == len(parts)-1 {
child := NewNode(x)
parent.Append(child)
s[currentPath+x+pathIDSeparator] = child
continue
}
currentPath = currentPath + x + pathIDSeparator
_, ok := s[currentPath]
if !ok {
s[currentPath] = NewNode(currentPath)
}
parent = s[currentPath]
}
return err
})
return root, walkErr
}