chokidar icon indicating copy to clipboard operation
chokidar copied to clipboard

ignoreInitial option doesn’t work for symlinks when not using fsevents

Open Mr0grog opened this issue 6 years ago • 2 comments

Describe the bug

Setting the ignoreInitial option to true should always suppress the initial add event when a file/directory/symlink is discovered. However, if you aren’t using fsevents, symlinks still trigger initial add events.

If you have a directory structure like:

watched/
├── file1.txt
└── file2.txt (symlink to `./file1.txt`)

And you run:

const chokidar = require('chokidar');
chokidar.watch('./watched', {
  followSymlinks: false,
  ignoreInitial: true,
  useFsEvents: false  // optional if not on MacOS
}).on('add', path => console.log('Added:', path));

Nothing should be logged until a new file is added. Instead, the above code immediately logs an add event for file2.txt.

I’m pretty sure the issue is that this.options.ignoreInitial is not checked in NodeFsHandler._handleSymlink() before emitting an add event on the last line here: https://github.com/paulmillr/chokidar/blob/20cb7672cb25a843df4d86475ffa8e4a8dc704b1/lib/nodefs-handler.js#L324-L326

…but I think just adding a check around that line probably isn’t adequate; _handleSymlink() needs an argument to know whether it is on the initialAdd just like _handleFile() has.

I’m happy to work on a PR for this if you’d like.

Versions (please complete the following information):

  • Chokidar version 2.1.2
  • Node version 10.15.1
  • OS version: MacOS 10.14.3, Debian 9.7 (via Docker)

To Reproduce

See description above.

Additional context

Ran into this while trying to help a client get their app (and associated Gulp watch scripts) running in Docker. Everyone is using a Mac and is experiencing the non-fsevents situation for the first time when it’s running in Docker.

Mr0grog avatar Feb 22 '19 23:02 Mr0grog

@Mr0grog did you find any workaround? Same situation here (chokidar 3.0.2, macOS 10.14.5, Docker on Ubuntu 16.04 and on macOS).

kachkaev avatar Aug 03 '19 13:08 kachkaev

@kachkaev In my case, I was able to write ignore patterns to cover most of our symlinks, so it wasn’t too painful to turn on followSymlinks as a workaround. This was for Gulp, but the straight Chokidar version would be like:

const chokidar = require('chokidar');
const os = require('os');

chokidar.watch('./watched', {
  // Turn on followSymlinks on non-MacOS systems to avoid a Chokidar bug in
  // Linux/Docker: https://github.com/paulmillr/chokidar/issues/804
  // This shouldn't be a big deal since we generally set `ignored` to handle
  // paths that might include symlinks.
  // TODO: always set this to `false` when that bug is fixed.
  followSymlinks: os.platform() !== 'darwin',
  ignoreInitial: true,

  // Ignore directories that are just full of symlinks
  ignored: /(?:^|\/)(?:some-symlink-dir|other-symlink-dir)(?:$|\/)/
}).on('some-event', path => console.log('Event for:', path));

I think I may have also added some debouncing to some event handlers to mitigate the results of following the symlinks I couldn’t ignore.

Mr0grog avatar Aug 03 '19 21:08 Mr0grog