Skip to content

Commit

Permalink
fix #2640: watch mode checks readdir, not stat
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Oct 29, 2022
1 parent 223e6ea commit 97d6dba
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog

## Unreleased

* Fix watch mode constantly rebuilding if the parent directory is inaccessible ([#2640](https://github.com/evanw/esbuild/issues/2640))

Android is unusual in that it has an inaccessible directory in the path to the root, which esbuild was not originally built to handle. To handle cases like this, the path resolution layer in esbuild has a hack where it treats inaccessible directories as empty. However, esbuild's watch implementation currently triggers a rebuild if a directory previously encountered an error but the directory now exists. The assumption is that the previous error was caused by the directory not existing. Although that's usually the case, it's not the case for this particular parent directory on Android. Instead the error is that the directory previously existed but was inaccessible.

This discrepancy between esbuild's path resolution layer and its watch mode was causing watch mode to rebuild continuously on Android. With this release, esbuild's watch mode instead checks for an error status change in the `readdir` file system call, so watch mode should no longer rebuild continuously on Android.

## 0.15.12

* Fix minifier correctness bug with single-use substitutions ([#2619](https://github.com/evanw/esbuild/issues/2619))
Expand Down
10 changes: 5 additions & 5 deletions internal/fs/fs_real.go
Expand Up @@ -42,7 +42,7 @@ type watchState uint8
const (
stateNone watchState = iota
stateDirHasAccessedEntries // Compare "accessedEntries"
stateDirMissing // Compare directory presence
stateDirUnreadable // Compare directory readability
stateFileHasModKey // Compare "modKey"
stateFileNeedModKey // Need to transition to "stateFileHasModKey" or "stateFileUnusableModKey" before "WatchData()" returns
stateFileMissing // Compare file presence
Expand Down Expand Up @@ -170,7 +170,7 @@ func (fs *realFS) ReadDirectory(dir string) (entries DirEntries, canonicalError
fs.watchMutex.Lock()
state := stateDirHasAccessedEntries
if canonicalError != nil {
state = stateDirMissing
state = stateDirUnreadable
}
entries.accessedEntries = &accessedEntries{wasPresent: make(map[string]bool)}
fs.watchData[dir] = privateWatchData{
Expand Down Expand Up @@ -465,10 +465,10 @@ func (fs *realFS) WatchData() WatchData {
}

switch data.state {
case stateDirMissing:
case stateDirUnreadable:
paths[path] = func() string {
info, err := os.Stat(path)
if err == nil && info.IsDir() {
_, err, _ := fs.readdir(path)
if err == nil {
return path
}
return ""
Expand Down

0 comments on commit 97d6dba

Please sign in to comment.