-
Notifications
You must be signed in to change notification settings - Fork 1
/
fileset.go
113 lines (107 loc) · 2.3 KB
/
fileset.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package building
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
)
func makeFileset(dir, includes, excludes string) fileset {
return fileset{
dir: dir,
includes: strings.Split(includes, ","),
excludes: strings.Split(excludes, ","),
}
}
type fileset struct {
dir string
includes []string
excludes []string
}
func resolve(filesets []fileset, fail bool) ([]fileset, error) {
var fs []fileset
for _, f := range filesets {
fss, err := f.glob(fail)
if err != nil {
return nil, err
}
fs = append(fs, fss)
}
return fs, nil
}
func (f fileset) glob(fail bool) (fileset, error) {
var paths []string
for _, include := range f.includes {
if f.dir != "" && !filepath.IsAbs(include) {
include = filepath.Join(f.dir, include)
}
include = filepath.Clean(include)
matches, err := filepath.Glob(include)
if err != nil {
return f, err
}
if matches != nil {
for _, match := range matches {
if f.dir != "" {
match, err = filepath.Rel(f.dir, match)
if err != nil {
return f, err
}
}
paths = append(paths, filepath.ToSlash(match))
}
} else if fail {
return f, fmt.Errorf("file %q does not exist", include)
}
}
if fail && len(paths) == 0 {
return f, fmt.Errorf("no source files")
}
f.includes = paths
return f, nil
}
func (f fileset) walk(fn func(path, rel string, info os.FileInfo, err error) error) error {
paths := make(map[string]bool)
for _, include := range f.includes {
if f.dir != "" && !filepath.IsAbs(include) {
include = filepath.Join(f.dir, include)
}
if err := filepath.Walk(include, func(p string, info os.FileInfo, err error) error {
if err != nil {
return err
}
rel := p
if f.dir != "" {
rel, err = filepath.Rel(f.dir, rel)
if err != nil {
return err
}
} else {
rel, err = filepath.Rel(include, rel)
if err != nil {
return err
}
rel = filepath.Join(filepath.Base(include), rel)
}
rel = filepath.ToSlash(rel)
if paths[rel] {
return nil
}
paths[rel] = true
for _, exclude := range f.excludes {
skip, err := path.Match(exclude, rel)
if err != nil {
return err
}
if skip {
b.Debugf("excluded %q", p)
return filepath.SkipDir
}
}
return fn(p, rel, info, err)
}); err != nil {
return err
}
}
return nil
}