Ensure watchPath
"de-normalizes" filesystem event paths if opted into…
#1286
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
…so that users of
watchPath
don't have to do their own realpath resolution.I've been going through the PulsarNext package tests in order to fix some regressions. Many of them are related to file-change monitoring in one way or another. For all its faults, the old
pathwatcher
was able to start watching a file for changes in a totally synchronous manner (don't ask me how), which made it quite easy to write tests around. The newpathwatcher
has the same synchronous API, but cannot guarantee instant subscription in an environment (like a spec suite!) where unsubscription and resubscription happen in rapid succession. This is annoying.For this reason and others — like not wanting to be maintainers of our own file-watching library — we have a medium-term goal to replace our own
pathwatcher
library withnsfw
across the board. In fact, the goal is convert usages ofpathwatcher
to a newer file-watching interface defined by Atom calledwatchPath
; the idea is that we'd be further away from the bare metal of a particular file-watching library and could more easily migrate to a different one in the future should the need arise.For that reason, I’ve tried to seize opportunities to convert usages of
pathwatcher
towatchPath
.But there’s a problem I’ve had to solve each time. Consider this
pathwatcher
code:Here’s the rough analog of that code using
watchPath
:This reflects the fact that
watchPath
watches directories, not individual files.But this doesn’t work out of the box on my machine — the specs that test this behavior will fail.
Here’s why: the specs rely on the
temp
module to generate directories within/tmp
to use as temporaryATOM_HOME
s and the like… but on macOS, everything in/tmp
is actually symlinked to/private/tmp
! SowatchPath
will normalize the desired path to something that starts with/private/tmp
, and all the filesystem events within the callback will havepath
andoldPath
properties that start with/private/tmp
. So all the equality checks will fail.But this isn’t just a problem with specs, since symlinks can happen anywhere. So it needs fixing in the general case.
There’s one way to fix this that works just fine as long as you already know that
userSnippetsFile
exists and is an absolute path:But it’s not nice to make each consumer do this work when
watchPath
itself could handle it instead. That’s what this PR does:watchPath
(which previously had no options — just an empty placeholder for future options!) calledrealPaths
. It defaults totrue
.{ realPaths: false }
. When they do…watchPath
creates aPathWatcher
instance, and multiplePathWatcher
s are likely to share a single instance ofNativeWatcher
.NativeWatcher
will contain the canonical path on disk for the file and can be given to multiplePathWatcher
s…PathWatcher
knows the path the user specified and can generate its own custom “denormalized” version of the event with the paths the user might expect. (If no symlinks are involved, thenPathWatcher
will re-use the existing event.)This is how
watchPath
should always have worked. I tried very hard to convince myself to make this the new default behavior… but it would theoretically be a breaking change, even though I doubt it would affect many packages.At any rate, lots of packages won’t be using this API directly; they’ll use the
File
andDirectory
classes that are exported fromatom
. Those have been around for much longer and have built-in change monitoring viaonDidChange
,onDidDelete
, et cetera.But
atom
getsFile
andDirectory
straight frompathwatcher
. If we really want to reduce reliance onpathwatcher
, we’ll need to build newFile
andDirectory
wrappers that can behave identically enough but usewatchPath
. I’ll see about doing that as well.