@@ -242,7 +242,7 @@ func configFilesWatcher(
242242 // needed for lastContents and lastIncludes because they get updated in multiple goroutines
243243 mu := sync.Mutex {}
244244
245- checkForContentChangesBeforeCallback := func () {
245+ parseAndCompareBeforeCallback := func () {
246246 currentContents , currentIncludes , err := parseYAMLIncludes (mainFilePath )
247247 if err != nil {
248248 onErr (fmt .Errorf ("parsing main file contents for comparison: %w" , err ))
@@ -268,15 +268,22 @@ func configFilesWatcher(
268268
269269 const debounceDuration = 500 * time .Millisecond
270270 var debounceTimer * time.Timer
271- debouncedCallback := func () {
271+ debouncedParseAndCompareBeforeCallback := func () {
272272 if debounceTimer != nil {
273273 debounceTimer .Stop ()
274274 debounceTimer .Reset (debounceDuration )
275275 } else {
276- debounceTimer = time .AfterFunc (debounceDuration , checkForContentChangesBeforeCallback )
276+ debounceTimer = time .AfterFunc (debounceDuration , parseAndCompareBeforeCallback )
277277 }
278278 }
279279
280+ deleteLastInclude := func (filePath string ) {
281+ mu .Lock ()
282+ defer mu .Unlock ()
283+ fileAbsPath , _ := filepath .Abs (filePath )
284+ delete (lastIncludes , fileAbsPath )
285+ }
286+
280287 go func () {
281288 for {
282289 select {
@@ -285,16 +292,33 @@ func configFilesWatcher(
285292 return
286293 }
287294 if event .Has (fsnotify .Write ) {
288- debouncedCallback ()
295+ debouncedParseAndCompareBeforeCallback ()
296+ } else if event .Has (fsnotify .Rename ) {
297+ // on linux the file will no longer be watched after a rename, on windows
298+ // it will continue to be watched with the new name but we have no access to
299+ // the new name in this event in order to stop watching it manually and match the
300+ // behavior in linux, may lead to weird unintended behaviors on windows as we're
301+ // only handling renames from linux's perspective
302+ // see https://github.com/fsnotify/fsnotify/issues/255
303+
304+ // remove the old file from our manually tracked includes, calling
305+ // debouncedParseAndCompareBeforeCallback will re-add it if it's still
306+ // required after it triggers
307+ deleteLastInclude (event .Name )
308+
309+ // wait for file to maybe get created again
310+ // see https://github.com/glanceapp/glance/pull/358
311+ for i := 0 ; i < 10 ; i ++ {
312+ if _ , err := os .Stat (event .Name ); err == nil {
313+ break
314+ }
315+ time .Sleep (200 * time .Millisecond )
316+ }
317+
318+ debouncedParseAndCompareBeforeCallback ()
289319 } else if event .Has (fsnotify .Remove ) {
290- func () {
291- mu .Lock ()
292- defer mu .Unlock ()
293- fileAbsPath , _ := filepath .Abs (event .Name )
294- delete (lastIncludes , fileAbsPath )
295- }()
296-
297- debouncedCallback ()
320+ deleteLastInclude (event .Name )
321+ debouncedParseAndCompareBeforeCallback ()
298322 }
299323 case err , isOpen := <- watcher .Errors :
300324 if ! isOpen {
0 commit comments