@@ -21,17 +21,13 @@ import (
21
21
"fmt"
22
22
"io"
23
23
"os"
24
- "path/filepath"
25
24
"sort"
26
25
"time"
27
26
28
- "github.com/fsnotify/fsnotify"
29
27
"github.com/pkg/errors"
30
28
"github.com/sirupsen/logrus"
31
29
)
32
30
33
- const quietPeriod = 500 * time .Millisecond
34
-
35
31
// WatcherFactory can build Watchers from a list of files to be watched for changes
36
32
type WatcherFactory func (paths []string ) (Watcher , error )
37
33
@@ -42,20 +38,14 @@ type Watcher interface {
42
38
Start (ctx context.Context , out io.Writer , onChange func ([]string ) error ) error
43
39
}
44
40
45
- // fsWatcher uses inotify to watch for changes and implements
46
- // the Watcher interface
47
- type fsWatcher struct {
48
- watcher * fsnotify.Watcher
49
- files map [string ]bool
50
- }
51
-
41
+ // mtimeWatcher uses polling on file mTimes.
52
42
type mtimeWatcher struct {
53
43
files map [string ]time.Time
54
44
}
55
45
56
46
func (m * mtimeWatcher ) Start (ctx context.Context , out io.Writer , onChange func ([]string ) error ) error {
57
-
58
47
c := time .NewTicker (2 * time .Second )
48
+ defer c .Stop ()
59
49
60
50
changedPaths := map [string ]bool {}
61
51
@@ -94,95 +84,22 @@ func (m *mtimeWatcher) Start(ctx context.Context, out io.Writer, onChange func([
94
84
95
85
// NewWatcher creates a new Watcher on a list of files.
96
86
func NewWatcher (paths []string ) (Watcher , error ) {
97
- sort . Strings ( paths )
87
+ logrus . Info ( "Starting mtime file watcher." )
98
88
99
- // Get the watcher type to use, defaulting to mtime.
100
- watcher := os .Getenv ("SKAFFOLD_FILE_WATCHER" )
101
- if watcher == "" {
102
- watcher = "mtime"
103
- }
89
+ sort .Strings (paths )
104
90
105
- switch watcher {
106
- case "mtime" :
107
- logrus .Info ("Starting mtime file watcher." )
108
- files := map [string ]time.Time {}
109
- for _ , p := range paths {
110
- fi , err := os .Stat (p )
111
- if err != nil {
112
- return nil , err
113
- }
114
- files [p ] = fi .ModTime ()
115
- }
116
- return & mtimeWatcher {
117
- files : files ,
118
- }, nil
119
- case "fsnotify" :
120
- logrus .Info ("Starting fsnotify file watcher." )
121
- w , err := fsnotify .NewWatcher ()
91
+ files := map [string ]time.Time {}
92
+ for _ , p := range paths {
93
+ fi , err := os .Stat (p )
122
94
if err != nil {
123
- return nil , errors .Wrapf (err , "creating watcher" )
124
- }
125
-
126
- files := map [string ]bool {}
127
-
128
- for _ , p := range paths {
129
- files [p ] = true
130
- logrus .Debugf ("Added watch for %s" , p )
131
-
132
- if err := w .Add (p ); err != nil {
133
- w .Close ()
134
- return nil , errors .Wrapf (err , "adding watch for %s" , p )
135
- }
136
-
137
- if err := w .Add (filepath .Dir (p )); err != nil {
138
- w .Close ()
139
- return nil , errors .Wrapf (err , "adding watch for %s" , p )
140
- }
95
+ return nil , errors .Wrapf (err , "statting file %s" , p )
141
96
}
142
- return & fsWatcher {
143
- watcher : w ,
144
- files : files ,
145
- }, nil
97
+ files [p ] = fi .ModTime ()
146
98
}
147
- return nil , fmt .Errorf ("unknown watch type: %s" , watcher )
148
- }
149
-
150
- // Start watches a set of files for changes, and calls `onChange`
151
- // on each file change.
152
- func (f * fsWatcher ) Start (ctx context.Context , out io.Writer , onChange func ([]string ) error ) error {
153
- changedPaths := map [string ]bool {}
154
99
155
- timer := time .NewTimer (1 << 63 - 1 ) // Forever
156
- defer timer .Stop ()
157
-
158
- for {
159
- select {
160
- case ev := <- f .watcher .Events :
161
- if ev .Op == fsnotify .Chmod {
162
- continue // TODO(dgageot): VSCode seems to chmod randomly
163
- }
164
- if ! f .files [ev .Name ] {
165
- continue // File is not directly watched. Maybe its parent is
166
- }
167
- timer .Reset (quietPeriod )
168
- logrus .Infof ("Change: %s" , ev )
169
- changedPaths [ev .Name ] = true
170
- case err := <- f .watcher .Errors :
171
- return errors .Wrap (err , "watch error" )
172
- case <- timer .C :
173
- changes := sortedPaths (changedPaths )
174
- changedPaths = map [string ]bool {}
175
-
176
- if err := onChange (changes ); err != nil {
177
- return errors .Wrap (err , "change callback" )
178
- }
179
-
180
- fmt .Fprintln (out , "Watching for changes..." )
181
- case <- ctx .Done ():
182
- f .watcher .Close ()
183
- return nil
184
- }
185
- }
100
+ return & mtimeWatcher {
101
+ files : files ,
102
+ }, nil
186
103
}
187
104
188
105
func sortedPaths (changedPaths map [string ]bool ) []string {
0 commit comments