move inotify watcher to library

This commit is contained in:
leaf corcoran 2016-04-13 19:47:27 -07:00
parent c5cbf3315e
commit fdfd314ebc
4 changed files with 159 additions and 101 deletions

View File

@ -194,49 +194,12 @@ local function create_watcher(files)
inotify = require "inotify"
end)
if inotify then
local dirs = {}
local watchers = require("moonscript.cmd.watchers")
for _, tuple in ipairs(files) do
local dir = parse_dir(tuple[1])
if dir == "" then
dir = "./"
end
table.insert(dirs, dir)
if watchers.InotifyWacher:available() then
return watchers.InotifyWacher(files):each_update()
end
dirs = remove_dups(dirs)
return coroutine.wrap(function()
io.stderr:write(("%s with inotify [%s]"):format(msg, plural(#dirs, "dir")) .. "\n")
local wd_table = {}
local handle = inotify.init()
for _, dir in ipairs(dirs) do
local wd = handle:addwatch(dir, inotify.IN_CLOSE_WRITE, inotify.IN_MOVED_TO)
wd_table[wd] = dir
end
while true do
local events = handle:read()
if not events then
break
end
for _, ev in ipairs(events) do
local fname = ev.name
if fname:match("%.moon$") then
local dir = wd_table[ev.wd]
if dir ~= "./" then
fname = dir .. fname
end
-- TODO: check to make sure the file was in the original set
coroutine.yield(fname)
end
end
end
end)
else
-- poll the filesystem instead
local sleep = get_sleep_func()
return coroutine.wrap(function()
@ -264,7 +227,6 @@ local function create_watcher(files)
end
end)
end
end
if opts.w then

View File

@ -1,29 +0,0 @@
remove_dupes = (list, key_fn) ->
seen = {}
return for item in *list
key = if key_fn then key_fn item else item
continue if seen[key]
seen[key] = true
item
-- files is a list of tuples, {source, target}
class Watcher
new: (@file_list) =>
class InotifyWacher extends Watcher
@available: =>
pcall -> require "inotify"
get_dirs: =>
import parse_dir from require "moonscript.cmd.moonc"
dirs = for {file_path} in *@file_list
dir = parse_dir file_path
dir = "./" if dir == ""
dir
remove_dupes dirs
class SleepWatcher
{:Watcher, :SleepWatcher, :InotifyWacher}

View File

@ -31,10 +31,16 @@ remove_dupes = function(list, key_fn)
return _accum_0
end)()
end
local plural
plural = function(count, word)
return tostring(count) .. " " .. tostring(word) .. tostring(count == 1 and "" or "s")
end
local Watcher
do
local _class_0
local _base_0 = { }
local _base_0 = {
start_msg = "Starting watch loop (Ctrl-C to exit)"
}
_base_0.__index = _base_0
_class_0 = setmetatable({
__init = function(self, file_list)
@ -81,6 +87,46 @@ do
dirs = _accum_0
end
return remove_dupes(dirs)
end,
each_update = function(self)
return coroutine.wrap(function()
local dirs = self:get_dirs()
io.stderr:write(tostring(self.start_msg) .. " with inotify [" .. tostring(plural(#dirs, "dir")) .. "]\n")
local wd_table = { }
local inotify = require("inotify")
local handle = inotify.init()
for _index_0 = 1, #dirs do
local dir = dirs[_index_0]
local wd = handle:addwatch(dir, inotify.IN_CLOSE_WRITE, inotify.IN_MOVED_TO)
wd_table[wd] = dir
end
while true do
local events = handle:read()
if not (events) then
break
end
for _index_0 = 1, #events do
local _continue_0 = false
repeat
local ev = events[_index_0]
local fname = ev.name
if not (fname:match("%.moon$")) then
_continue_0 = true
break
end
local dir = wd_table[ev.wd]
if dir ~= "./" then
fname = dir .. fname
end
coroutine.yield(fname)
_continue_0 = true
until true
if not _continue_0 then
break
end
end
end
end)
end
}
_base_0.__index = _base_0
@ -125,14 +171,29 @@ end
local SleepWatcher
do
local _class_0
local _parent_0 = Watcher
local _base_0 = { }
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
__init = function() end,
__init = function(self, ...)
return _class_0.__parent.__init(self, ...)
end,
__base = _base_0,
__name = "SleepWatcher"
__name = "SleepWatcher",
__parent = _parent_0
}, {
__index = _base_0,
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil then
local parent = rawget(cls, "__parent")
if parent then
return parent[name]
end
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -140,6 +201,9 @@ do
end
})
_base_0.__class = _class_0
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
SleepWatcher = _class_0
end
return {

View File

@ -0,0 +1,61 @@
remove_dupes = (list, key_fn) ->
seen = {}
return for item in *list
key = if key_fn then key_fn item else item
continue if seen[key]
seen[key] = true
item
plural = (count, word) ->
"#{count} #{word}#{count == 1 and "" or "s"}"
-- files is a list of tuples, {source, target}
class Watcher
start_msg: "Starting watch loop (Ctrl-C to exit)"
new: (@file_list) =>
class InotifyWacher extends Watcher
@available: =>
pcall -> require "inotify"
get_dirs: =>
import parse_dir from require "moonscript.cmd.moonc"
dirs = for {file_path} in *@file_list
dir = parse_dir file_path
dir = "./" if dir == ""
dir
remove_dupes dirs
-- creates an iterator that yields a file every time it's updated
-- TODO: detect when new files are added to directories
each_update: =>
coroutine.wrap ->
dirs = @get_dirs!
io.stderr\write "#{@start_msg} with inotify [#{plural #dirs, "dir"}]\n"
wd_table = {}
inotify = require "inotify"
handle = inotify.init!
for dir in *dirs
wd = handle\addwatch dir, inotify.IN_CLOSE_WRITE, inotify.IN_MOVED_TO
wd_table[wd] = dir
while true
events = handle\read!
break unless events -- error?
for ev in *events
fname = ev.name
continue unless fname\match "%.moon$"
dir = wd_table[ev.wd]
fname = dir .. fname if dir != "./"
-- TODO: check to make sure the file was in the original set
coroutine.yield(fname)
class SleepWatcher extends Watcher
{:Watcher, :SleepWatcher, :InotifyWacher}