mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
move inotify watcher to library
This commit is contained in:
parent
c5cbf3315e
commit
fdfd314ebc
98
bin/moonc
98
bin/moonc
@ -194,76 +194,38 @@ 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)
|
||||
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()
|
||||
io.stderr:write(("%s with polling [%s]"):format(msg, plural(#files, "file")) .. "\n")
|
||||
|
||||
local mod_time = {}
|
||||
while true do
|
||||
for _, tuple in ipairs(files) do
|
||||
local file = tuple[1]
|
||||
local time = lfs.attributes(file, "modification")
|
||||
if not time then
|
||||
mod_time[file] = nil -- file doesn't exist
|
||||
elseif not mod_time[file] then
|
||||
mod_time[file] = time -- new file created
|
||||
else
|
||||
if time ~= mod_time[file] then
|
||||
if time > mod_time[file] then
|
||||
coroutine.yield(file)
|
||||
mod_time[file] = time
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
sleep(polling_rate)
|
||||
end
|
||||
end)
|
||||
if watchers.InotifyWacher:available() then
|
||||
return watchers.InotifyWacher(files):each_update()
|
||||
end
|
||||
|
||||
-- poll the filesystem instead
|
||||
local sleep = get_sleep_func()
|
||||
return coroutine.wrap(function()
|
||||
io.stderr:write(("%s with polling [%s]"):format(msg, plural(#files, "file")) .. "\n")
|
||||
|
||||
local mod_time = {}
|
||||
while true do
|
||||
for _, tuple in ipairs(files) do
|
||||
local file = tuple[1]
|
||||
local time = lfs.attributes(file, "modification")
|
||||
if not time then
|
||||
mod_time[file] = nil -- file doesn't exist
|
||||
elseif not mod_time[file] then
|
||||
mod_time[file] = time -- new file created
|
||||
else
|
||||
if time ~= mod_time[file] then
|
||||
if time > mod_time[file] then
|
||||
coroutine.yield(file)
|
||||
mod_time[file] = time
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
sleep(polling_rate)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
|
@ -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}
|
@ -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 {
|
61
moonscript/cmd/watchers.moon
Normal file
61
moonscript/cmd/watchers.moon
Normal 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}
|
Loading…
Reference in New Issue
Block a user