mirror of
https://github.com/janet-lang/janet
synced 2025-01-20 20:26:51 +00:00
Begin standardizing of event properties for filewatch.
- `:file-name` for the name of the file that triggered the event. - `:dir-name` for the containing directory of the file - `:type` for the event type.
This commit is contained in:
parent
5a199716cb
commit
90018b35c0
@ -213,8 +213,25 @@ static void watcher_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
|
|||||||
JanetKV *event = janet_struct_begin(6);
|
JanetKV *event = janet_struct_begin(6);
|
||||||
janet_struct_put(event, janet_ckeywordv("wd"), janet_wrap_integer(inevent.wd));
|
janet_struct_put(event, janet_ckeywordv("wd"), janet_wrap_integer(inevent.wd));
|
||||||
janet_struct_put(event, janet_ckeywordv("wd-path"), path);
|
janet_struct_put(event, janet_ckeywordv("wd-path"), path);
|
||||||
janet_struct_put(event, janet_ckeywordv("mask"), janet_wrap_integer(inevent.mask));
|
if (janet_checktype(name, JANET_NIL)) {
|
||||||
janet_struct_put(event, janet_ckeywordv("path"), name);
|
/* We were watching a file directly, so path is the full path. Split into dirname / basename */
|
||||||
|
JanetString spath = janet_unwrap_string(path);
|
||||||
|
const uint8_t *cursor = spath + janet_string_length(spath);
|
||||||
|
const uint8_t *cursor_end = cursor;
|
||||||
|
while (cursor > spath && cursor[0] != '/') {
|
||||||
|
cursor--;
|
||||||
|
}
|
||||||
|
if (cursor == spath) {
|
||||||
|
janet_struct_put(event, janet_ckeywordv("dir-name"), path);
|
||||||
|
janet_struct_put(event, janet_ckeywordv("file-name"), name);
|
||||||
|
} else {
|
||||||
|
janet_struct_put(event, janet_ckeywordv("dir-name"), janet_wrap_string(janet_string(spath, (cursor - spath))));
|
||||||
|
janet_struct_put(event, janet_ckeywordv("file-name"), janet_wrap_string(janet_string(cursor + 1, (cursor_end - cursor - 1))));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
janet_struct_put(event, janet_ckeywordv("dir-name"), path);
|
||||||
|
janet_struct_put(event, janet_ckeywordv("file-name"), name);
|
||||||
|
}
|
||||||
janet_struct_put(event, janet_ckeywordv("cookie"), janet_wrap_integer(inevent.cookie));
|
janet_struct_put(event, janet_ckeywordv("cookie"), janet_wrap_integer(inevent.cookie));
|
||||||
Janet etype = janet_ckeywordv("type");
|
Janet etype = janet_ckeywordv("type");
|
||||||
const JanetWatchFlagName *wfn_end = watcher_flags_linux + sizeof(watcher_flags_linux) / sizeof(watcher_flags_linux[0]);
|
const JanetWatchFlagName *wfn_end = watcher_flags_linux + sizeof(watcher_flags_linux) / sizeof(watcher_flags_linux[0]);
|
||||||
@ -392,7 +409,7 @@ static void watcher_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
|
|||||||
JanetKV *event = janet_struct_begin(3);
|
JanetKV *event = janet_struct_begin(3);
|
||||||
janet_struct_put(event, janet_ckeywordv("type"), janet_ckeywordv(watcher_actions_windows[fni->Action]));
|
janet_struct_put(event, janet_ckeywordv("type"), janet_ckeywordv(watcher_actions_windows[fni->Action]));
|
||||||
janet_struct_put(event, janet_ckeywordv("file-name"), filename);
|
janet_struct_put(event, janet_ckeywordv("file-name"), filename);
|
||||||
janet_struct_put(event, janet_ckeywordv("dir"), janet_wrap_string(ow->dir_path));
|
janet_struct_put(event, janet_ckeywordv("dir-name"), janet_wrap_string(ow->dir_path));
|
||||||
Janet eventv = janet_wrap_struct(janet_struct_end(event));
|
Janet eventv = janet_wrap_struct(janet_struct_end(event));
|
||||||
|
|
||||||
janet_channel_give(watcher->channel, eventv);
|
janet_channel_give(watcher->channel, eventv);
|
||||||
@ -558,7 +575,19 @@ static const JanetAbstractType janet_filewatch_at = {
|
|||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_make,
|
JANET_CORE_FN(cfun_filewatch_make,
|
||||||
"(filewatch/new channel &opt default-flags)",
|
"(filewatch/new channel &opt default-flags)",
|
||||||
"Create a new filewatcher that will give events to a channel channel.") {
|
"Create a new filewatcher that will give events to a channel channel. See `filewatch/add` for available flags.\n\n"
|
||||||
|
"When an event is triggered by the filewatcher, a struct containing information will be given to channel as with `ev/give`. "
|
||||||
|
"The contents of the channel depend on the OS, but will contain some common keys:\n\n"
|
||||||
|
"* `:type` -- the type of the event that was raised.\n\n"
|
||||||
|
"* `:file-name` -- the base file name of the file that triggered the event.\n\n"
|
||||||
|
"* `:dir-name` -- the directory name of the file that triggered the event.\n\n"
|
||||||
|
"Events also will contain keys specific to the host OS.\n\n"
|
||||||
|
"Windows has no extra properties on events.\n\n"
|
||||||
|
"Linux has the following extra properties on events:\n\n"
|
||||||
|
"* `:wd` -- the integer key returned by `filewatch/add` for the path that triggered this.\n\n"
|
||||||
|
"* `:wd-path` -- the string path for watched directory of file. For files, will be the same as `:file-name`, and for directories, will be the same as `:dir-name`.\n\n"
|
||||||
|
"* `:cookie` -- a randomized integer used to associate related events, such as :moved-from and :moved-to events.\n\n"
|
||||||
|
"") {
|
||||||
janet_arity(argc, 1, -1);
|
janet_arity(argc, 1, -1);
|
||||||
JanetChannel *channel = janet_getchannel(argv, 0);
|
JanetChannel *channel = janet_getchannel(argv, 0);
|
||||||
JanetWatcher *watcher = janet_abstract(&janet_filewatch_at, sizeof(JanetWatcher));
|
JanetWatcher *watcher = janet_abstract(&janet_filewatch_at, sizeof(JanetWatcher));
|
||||||
@ -569,7 +598,43 @@ JANET_CORE_FN(cfun_filewatch_make,
|
|||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_add,
|
JANET_CORE_FN(cfun_filewatch_add,
|
||||||
"(filewatch/add watcher path &opt flags)",
|
"(filewatch/add watcher path &opt flags)",
|
||||||
"Add a path to the watcher.") {
|
"Add a path to the watcher. Available flags depend on the current OS, and are as follows:\n\n"
|
||||||
|
"Windows/MINGW (flags correspond to FILE_NOTIFY_CHANGE_* flags in win32 documentation):\n\n"
|
||||||
|
"* `:all` - trigger an event for all of the below triggers.\n\n"
|
||||||
|
"* `:attributes` - FILE_NOTIFY_CHANGE_ATTRIBUTES\n\n"
|
||||||
|
"* `:creation` - FILE_NOTIFY_CHANGE_CREATION\n\n"
|
||||||
|
"* `:dir-name` - FILE_NOTIFY_CHANGE_DIR_NAME\n\n"
|
||||||
|
"* `:last-access` - FILE_NOTIFY_CHANGE_LAST_ACCESS\n\n"
|
||||||
|
"* `:last-write` - FILE_NOTIFY_CHANGE_LAST_WRITE\n\n"
|
||||||
|
"* `:security` - FILE_NOTIFY_CHANGE_SECURITY\n\n"
|
||||||
|
"* `:size` - FILE_NOTIFY_CHANGE_SIZE\n\n"
|
||||||
|
"* `:recursive` - watch subdirectories recursively\n\n"
|
||||||
|
"Linux (flags correspond to IN_* flags from <sys/inotify.h>):\n\n"
|
||||||
|
"* `:access` - IN_ACCESS\n\n"
|
||||||
|
"* `:all` - IN_ALL_EVENTS\n\n"
|
||||||
|
"* `:attrib` - IN_ATTRIB\n\n"
|
||||||
|
"* `:close-nowrite` - IN_CLOSE_NOWRITE\n\n"
|
||||||
|
"* `:close-write` - IN_CLOSE_WRITE\n\n"
|
||||||
|
"* `:create` - IN_CREATE\n\n"
|
||||||
|
"* `:delete` - IN_DELETE\n\n"
|
||||||
|
"* `:delete-self` - IN_DELETE_SELF\n\n"
|
||||||
|
"* `:ignored` - IN_IGNORED\n\n"
|
||||||
|
"* `:modify` - IN_MODIFY\n\n"
|
||||||
|
"* `:move-self` - IN_MOVE_SELF\n\n"
|
||||||
|
"* `:moved-from` - IN_MOVED_FROM\n\n"
|
||||||
|
"* `:moved-to` - IN_MOVED_TO\n\n"
|
||||||
|
"* `:open` - IN_OPEN\n\n"
|
||||||
|
"* `:q-overflow` - IN_Q_OVERFLOW\n\n"
|
||||||
|
"* `:unmount` - IN_UNMOUNT\n\n\n"
|
||||||
|
"On Windows, events will have the following possible types:\n\n"
|
||||||
|
"* `:unknown`\n\n"
|
||||||
|
"* `:added`\n\n"
|
||||||
|
"* `:removed`\n\n"
|
||||||
|
"* `:modified`\n\n"
|
||||||
|
"* `:renamed-old`\n\n"
|
||||||
|
"* `:renamed-new`\n\n"
|
||||||
|
"On Linux, events will a `:type` corresponding to the possible flags, excluding `:all`.\n"
|
||||||
|
"") {
|
||||||
janet_arity(argc, 2, -1);
|
janet_arity(argc, 2, -1);
|
||||||
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
||||||
const char *path = janet_getcstring(argv, 1);
|
const char *path = janet_getcstring(argv, 1);
|
||||||
|
@ -38,13 +38,16 @@
|
|||||||
(gccollect)
|
(gccollect)
|
||||||
|
|
||||||
(defn- expect
|
(defn- expect
|
||||||
[key value]
|
[key value & more-kvs]
|
||||||
(ev/with-deadline
|
(ev/with-deadline
|
||||||
1
|
1
|
||||||
(def event (ev/take chan))
|
(def event (ev/take chan))
|
||||||
(when is-verbose (pp event))
|
(when is-verbose (pp event))
|
||||||
(assert event "check event")
|
(assert event "check event")
|
||||||
(assert (= value (get event key)) (string/format "got %p, expected %p" (get event key) value))))
|
(assert (= value (get event key)) (string/format "got %p, expected %p" (get event key) value))
|
||||||
|
(when (next more-kvs)
|
||||||
|
(each [k v] (partition 2 more-kvs)
|
||||||
|
(assert (= v (get event k)) (string/format "got %p, expected %p" (get event k) v))))))
|
||||||
|
|
||||||
(defn- expect-empty
|
(defn- expect-empty
|
||||||
[]
|
[]
|
||||||
@ -80,14 +83,18 @@
|
|||||||
(def fw (filewatch/new chan))
|
(def fw (filewatch/new chan))
|
||||||
(def td1 (randdir))
|
(def td1 (randdir))
|
||||||
(def td2 (randdir))
|
(def td2 (randdir))
|
||||||
|
(def td3 (randdir))
|
||||||
(rmrf td1)
|
(rmrf td1)
|
||||||
(rmrf td2)
|
(rmrf td2)
|
||||||
(os/mkdir td1)
|
(os/mkdir td1)
|
||||||
(os/mkdir td2)
|
(os/mkdir td2)
|
||||||
|
(os/mkdir td3)
|
||||||
|
(spit-file td3 "file3.txt")
|
||||||
(when is-win
|
(when is-win
|
||||||
(filewatch/add fw td1 :last-write :last-access :file-name :dir-name :size :attributes :recursive)
|
(filewatch/add fw td1 :last-write :last-access :file-name :dir-name :size :attributes :recursive)
|
||||||
(filewatch/add fw td2 :last-write :last-access :file-name :dir-name :size :attributes))
|
(filewatch/add fw td2 :last-write :last-access :file-name :dir-name :size :attributes))
|
||||||
(when is-linux
|
(when is-linux
|
||||||
|
(filewatch/add fw (string td3 "/file3.txt") :close-write :create :delete)
|
||||||
(filewatch/add fw td1 :close-write :create :delete)
|
(filewatch/add fw td1 :close-write :create :delete)
|
||||||
(filewatch/add fw td2 :close-write :create :delete :ignored))
|
(filewatch/add fw td2 :close-write :create :delete :ignored))
|
||||||
(assert-no-error "filewatch/listen no error" (filewatch/listen fw))
|
(assert-no-error "filewatch/listen no error" (filewatch/listen fw))
|
||||||
@ -98,7 +105,7 @@
|
|||||||
|
|
||||||
(when is-win
|
(when is-win
|
||||||
(spit-file td1 "file1.txt")
|
(spit-file td1 "file1.txt")
|
||||||
(expect :type :added)
|
(expect :type :added :file-name "file1.txt" :dir-name td1)
|
||||||
(expect :type :modified)
|
(expect :type :modified)
|
||||||
(expect-maybe :type :modified) # for mingw + wine
|
(expect-maybe :type :modified) # for mingw + wine
|
||||||
(gccollect)
|
(gccollect)
|
||||||
@ -144,7 +151,7 @@
|
|||||||
|
|
||||||
(when is-linux
|
(when is-linux
|
||||||
(spit-file td1 "file1.txt")
|
(spit-file td1 "file1.txt")
|
||||||
(expect :type :create)
|
(expect :type :create :file-name "file1.txt" :dir-name td1)
|
||||||
(expect :type :close-write)
|
(expect :type :close-write)
|
||||||
(expect-empty)
|
(expect-empty)
|
||||||
(gccollect)
|
(gccollect)
|
||||||
@ -153,6 +160,11 @@
|
|||||||
(expect-empty)
|
(expect-empty)
|
||||||
(gccollect)
|
(gccollect)
|
||||||
|
|
||||||
|
# Check file3.txt
|
||||||
|
(spit-file td3 "file3.txt")
|
||||||
|
(expect :type :close-write :file-name "file3.txt" :dir-name td3)
|
||||||
|
(expect-empty)
|
||||||
|
|
||||||
# Check td2
|
# Check td2
|
||||||
(spit-file td2 "file2.txt")
|
(spit-file td2 "file2.txt")
|
||||||
(expect :type :create)
|
(expect :type :create)
|
||||||
@ -187,5 +199,6 @@
|
|||||||
(assert-no-error "filewatch/unlisten no error" (filewatch/unlisten fw))
|
(assert-no-error "filewatch/unlisten no error" (filewatch/unlisten fw))
|
||||||
(assert-no-error "cleanup 1" (rmrf td1))
|
(assert-no-error "cleanup 1" (rmrf td1))
|
||||||
(assert-no-error "cleanup 2" (rmrf td2))
|
(assert-no-error "cleanup 2" (rmrf td2))
|
||||||
|
(assert-no-error "cleanup 3" (rmrf td3))
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user