mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-20 17:41:37 +00:00
Keep watching directories recreated at a removed path (AI-assisted)
This commit is contained in:
parent
a36a199835
commit
f54ade744d
4 changed files with 50 additions and 5 deletions
1
AI-canary.txt
Normal file
1
AI-canary.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
This pull request is AI generated
|
||||||
|
|
@ -32,8 +32,10 @@ Making a new release? Simply add the new header with the version and date undern
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
* LocalizationTables no longer report as changed when nothing changes. [(#1333)]
|
* LocalizationTables no longer report as changed when nothing changes. [(#1333)]
|
||||||
|
* Fixed live sync on Linux (`rojo serve` and the `--watch` modes) missing every change inside a directory that was removed or moved aside and then recreated at the same path within another synced directory. ([#1341])
|
||||||
|
|
||||||
[#1333]: https://github.com/rojo-rbx/rojo/pull/1333
|
[#1333]: https://github.com/rojo-rbx/rojo/pull/1333
|
||||||
|
[#1341]: https://github.com/rojo-rbx/rojo/pull/1341
|
||||||
|
|
||||||
## [7.7.1] (October 1st, 2026)
|
## [7.7.1] (October 1st, 2026)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
# memofs Changelog
|
# memofs Changelog
|
||||||
|
|
||||||
## Unreleased Changes
|
## Unreleased Changes
|
||||||
|
* Fixed `StdBackend` on Linux dropping the watches on a directory recreated at a path whose removal was committed afterwards, which stopped events for everything inside it. [#1341]
|
||||||
|
|
||||||
|
[#1341]: https://github.com/rojo-rbx/rojo/pull/1341
|
||||||
|
|
||||||
# 0.4.0 (2026-07-01)
|
# 0.4.0 (2026-07-01)
|
||||||
* Added `Vfs::canonicalize`. [#1201]
|
* Added `Vfs::canonicalize`. [#1201]
|
||||||
|
|
|
||||||
|
|
@ -122,15 +122,54 @@ impl VfsBackend for StdBackend {
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
// This recursive watch covers any watch we already hold below
|
||||||
|
// `path`. Release those, so that every path in `watches` is the
|
||||||
|
// only watch covering it and `unwatch` can trust that. Release them
|
||||||
|
// first: on inotify this watch shares their per-directory entries,
|
||||||
|
// and unwatching them afterwards would delete its coverage too.
|
||||||
|
let covered: Vec<PathBuf> = self
|
||||||
|
.watches
|
||||||
|
.iter()
|
||||||
|
.filter(|watched| watched.starts_with(path))
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
for watched in &covered {
|
||||||
|
self.watches.remove(watched);
|
||||||
|
let _ = self.watcher.unwatch(watched);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = self.watcher.watch(path, RecursiveMode::Recursive) {
|
||||||
|
// Put back what we released, so a failed watch loses nothing.
|
||||||
|
// inotify keeps whatever part of the walk succeeded, so drop
|
||||||
|
// that first to free its watches.
|
||||||
|
let _ = self.watcher.unwatch(path);
|
||||||
|
for watched in covered {
|
||||||
|
if self
|
||||||
|
.watcher
|
||||||
|
.watch(&watched, RecursiveMode::Recursive)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
self.watches.insert(watched);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(io::Error::other(err));
|
||||||
|
}
|
||||||
self.watches.insert(path.to_path_buf());
|
self.watches.insert(path.to_path_buf());
|
||||||
self.watcher
|
Ok(())
|
||||||
.watch(path, RecursiveMode::Recursive)
|
|
||||||
.map_err(io::Error::other)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwatch(&mut self, path: &Path) -> io::Result<()> {
|
fn unwatch(&mut self, path: &Path) -> io::Result<()> {
|
||||||
self.watches.remove(path);
|
// Only stop a watch we started. Any other path is covered by an
|
||||||
self.watcher.unwatch(path).map_err(io::Error::other)
|
// ancestor's recursive watch, for which inotify keeps an entry per
|
||||||
|
// directory, keyed by path. By the time a removal is committed, that
|
||||||
|
// entry may belong to a new directory created at the same path, and
|
||||||
|
// unwatching it would stop events for that directory and everything
|
||||||
|
// under it.
|
||||||
|
if self.watches.remove(path) {
|
||||||
|
self.watcher.unwatch(path).map_err(io::Error::other)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue