summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/GeertJohan/go.rice/walk.go
blob: 3042aeabf2ebabb453a93047abfcfe9396654247 (plain) (blame)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package rice

import (
	"os"
	"path/filepath"
	"sort"
	"strings"
)

// Walk is like filepath.Walk()
// Visit http://golang.org/pkg/path/filepath/#Walk for more information
func (b *Box) Walk(path string, walkFn filepath.WalkFunc) error {

	pathFile, err := b.Open(path)
	if err != nil {
		return err
	}
	defer pathFile.Close()

	pathInfo, err := pathFile.Stat()
	if err != nil {
		return err
	}

	if b.IsAppended() || b.IsEmbedded() {
		return b.walk(path, pathInfo, walkFn)
	}

	// We don't have any embedded or appended box so use live filesystem mode
	return filepath.Walk(b.absolutePath+string(os.PathSeparator)+path, func(path string, info os.FileInfo, err error) error {

		// Strip out the box name from the returned paths
		path = strings.TrimPrefix(path, b.absolutePath+string(os.PathSeparator))
		return walkFn(path, info, err)

	})

}

// walk recursively descends path.
// See walk() in $GOROOT/src/pkg/path/filepath/path.go
func (b *Box) walk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error {

	err := walkFn(path, info, nil)
	if err != nil {
		if info.IsDir() && err == filepath.SkipDir {
			return nil
		}
		return err
	}

	if !info.IsDir() {
		return nil
	}

	names, err := b.readDirNames(path)
	if err != nil {
		return walkFn(path, info, err)
	}

	for _, name := range names {

		filename := filepath.Join(path, name)
		fileObject, err := b.Open(filename)
		if err != nil {
			return err
		}
		defer fileObject.Close()

		fileInfo, err := fileObject.Stat()
		if err != nil {
			if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
				return err
			}
		} else {
			err = b.walk(filename, fileInfo, walkFn)
			if err != nil {
				if !fileInfo.IsDir() || err != filepath.SkipDir {
					return err
				}
			}
		}
	}

	return nil

}

// readDirNames reads the directory named by path and returns a sorted list of directory entries.
// See readDirNames() in $GOROOT/pkg/path/filepath/path.go
func (b *Box) readDirNames(path string) ([]string, error) {

	f, err := b.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	stat, err := f.Stat()
	if err != nil {
		return nil, err
	}

	if !stat.IsDir() {
		return nil, nil
	}

	infos, err := f.Readdir(0)
	if err != nil {
		return nil, err
	}

	var names []string

	for _, info := range infos {
		names = append(names, info.Name())
	}

	sort.Strings(names)
	return names, nil

}