fix(inotify): report .closed events separately from .modified events
This commit is contained in:
parent
95c7580a87
commit
99dec3f689
9 changed files with 59 additions and 1 deletions
|
|
@ -6,6 +6,7 @@ const ObjectType = types.ObjectType;
|
|||
|
||||
pub const watches_recursively = true; // FSEventStreamCreate watches the entire subtree
|
||||
pub const detects_file_modifications = true;
|
||||
pub const emits_close_events = false;
|
||||
|
||||
handler: *Handler,
|
||||
stream: ?*anyopaque, // FSEventStreamRef
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ pub fn Create(comptime variant: InterfaceType) type {
|
|||
|
||||
pub const watches_recursively = false;
|
||||
pub const detects_file_modifications = true;
|
||||
pub const emits_close_events = true;
|
||||
pub const polling = variant == .polling;
|
||||
|
||||
const WatchEntry = struct { path: []u8, is_dir: bool };
|
||||
|
|
@ -342,8 +343,10 @@ pub fn Create(comptime variant: InterfaceType) type {
|
|||
if (is_dir and self.has_watch_for_path(full_path))
|
||||
continue;
|
||||
break :blk .deleted;
|
||||
} else if (ev.mask & (IN.MODIFY | IN.CLOSE_WRITE) != 0)
|
||||
} else if (ev.mask & IN.MODIFY != 0)
|
||||
.modified
|
||||
else if (ev.mask & IN.CLOSE_WRITE != 0)
|
||||
.closed
|
||||
else
|
||||
continue;
|
||||
try self.handler.change(full_path, event_type, object_type);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const ObjectType = types.ObjectType;
|
|||
|
||||
pub const watches_recursively = false;
|
||||
pub const detects_file_modifications = true;
|
||||
pub const emits_close_events = false;
|
||||
|
||||
handler: *Handler,
|
||||
kq: std.posix.fd_t,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const ObjectType = types.ObjectType;
|
|||
|
||||
pub const watches_recursively = false;
|
||||
pub const detects_file_modifications = false;
|
||||
pub const emits_close_events = false;
|
||||
pub const WatchEntry = struct { fd: std.posix.fd_t, is_file: bool };
|
||||
|
||||
handler: *Handler,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const ObjectType = types.ObjectType;
|
|||
|
||||
pub const watches_recursively = true; // ReadDirectoryChangesW with bWatchSubtree=1
|
||||
pub const detects_file_modifications = true;
|
||||
pub const emits_close_events = false;
|
||||
|
||||
const windows = std.os.windows;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,12 +50,14 @@ const CliHandler = struct {
|
|||
const color: std.io.tty.Color = switch (event_type) {
|
||||
.created => .green,
|
||||
.modified => .blue,
|
||||
.closed => .bright_black,
|
||||
.deleted => .red,
|
||||
.renamed => .magenta,
|
||||
};
|
||||
const event_label = switch (event_type) {
|
||||
.created => "create ",
|
||||
.modified => "modify ",
|
||||
.closed => "close ",
|
||||
.deleted => "delete ",
|
||||
.renamed => "rename ",
|
||||
};
|
||||
|
|
@ -160,6 +162,7 @@ fn usage(out: std.fs.File) !void {
|
|||
\\Events printed to stdout (columns: event type path):
|
||||
\\ create a file or directory was created
|
||||
\\ modify a file was modified
|
||||
\\ close a file was closed after writing (Linux only)
|
||||
\\ delete a file or directory was deleted
|
||||
\\ rename a file or directory was renamed
|
||||
\\
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ pub fn Create(comptime variant: Variant) type {
|
|||
/// `watch()` do receive per-file `NOTE_WRITE` events and will report
|
||||
/// modifications.
|
||||
pub const detects_file_modifications = Backend.detects_file_modifications;
|
||||
pub const emits_close_events = Backend.emits_close_events;
|
||||
|
||||
/// Create a new watcher.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -245,6 +245,42 @@ fn testModifyFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
|||
try std.testing.expect(th.hasChange(file_path, .modified, .file));
|
||||
}
|
||||
|
||||
fn testCloseFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||
if (comptime !Watcher.emits_close_events) return error.SkipZigTest;
|
||||
|
||||
const TH = MakeTestHandler(Watcher);
|
||||
|
||||
const tmp = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(tmp);
|
||||
allocator.free(tmp);
|
||||
}
|
||||
|
||||
const th = try TH.init(allocator);
|
||||
defer th.deinit();
|
||||
|
||||
const file_path = try std.fs.path.join(allocator, &.{ tmp, "data.txt" });
|
||||
defer allocator.free(file_path);
|
||||
{
|
||||
const f = try std.fs.createFileAbsolute(file_path, .{});
|
||||
f.close();
|
||||
}
|
||||
|
||||
var watcher = try Watcher.init(allocator, &th.handler);
|
||||
defer watcher.deinit();
|
||||
try watcher.watch(tmp);
|
||||
|
||||
{
|
||||
const f = try std.fs.openFileAbsolute(file_path, .{ .mode = .write_only });
|
||||
defer f.close();
|
||||
try f.writeAll("hello nightwatch\n");
|
||||
}
|
||||
|
||||
try drainEvents(Watcher, &watcher);
|
||||
try std.testing.expect(th.hasChange(file_path, .modified, .file));
|
||||
try std.testing.expect(th.hasChange(file_path, .closed, .file));
|
||||
}
|
||||
|
||||
fn testDeleteFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||
const TH = MakeTestHandler(Watcher);
|
||||
|
||||
|
|
@ -578,6 +614,12 @@ test "writing to a file emits a 'modified' event" {
|
|||
}
|
||||
}
|
||||
|
||||
test "closing a file after writing emits a 'closed' event (inotify only)" {
|
||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
||||
try testCloseFile(nw.Create(variant), std.testing.allocator);
|
||||
}
|
||||
}
|
||||
|
||||
test "deleting a file emits a 'deleted' event" {
|
||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
||||
try testDeleteFile(nw.Create(variant), std.testing.allocator);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ pub const EventType = enum {
|
|||
created,
|
||||
/// A file's contents were modified.
|
||||
modified,
|
||||
/// A file was closed.
|
||||
///
|
||||
/// Only delivered by INotfiy (Linux) and only if the file was opened
|
||||
/// for writing.
|
||||
closed,
|
||||
/// A file or directory was deleted.
|
||||
deleted,
|
||||
/// A file or directory was renamed or moved.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue