Skip to content

Commit 596f6fb

Browse files
committed
Refactor moonc and overhaul watchers
- Essentially rewrote both SleepWatcher and InotifyWatcher - Added test suites for both, including an expanded set of filesystem stubs in order to test them in isolation from the underlying filesystem - The filesystem stubs have their own tests, kek Improvements as a result of these changes: - Watch mode will remove "orphaned" .lua output files if/when their corresponding .moon input files are deleted - But it will not remove .lua files that have no corresponding .moon file to begin with, in order to avoid e.g. removing vendored Lua modules - Both Watcher types will properly handle creation of new subdirectories - There *shouldn't* be any problematic races with this, although inotify's lack of recursive directory watching makes it difficult to know for sure - More of the code is tested, and more of the code now *could* be tested (but isn't yet) - Some bugs were fixed Downsides: - Somewhat gnarlier tests - Moar lines of code
1 parent 5d79bf7 commit 596f6fb

File tree

10 files changed

+968
-215
lines changed

10 files changed

+968
-215
lines changed

docs/command_line.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,38 @@ files in the same directories.
116116
$ moonc my_script1.moon my_script2.moon ...
117117
```
118118

119-
You can control where the compiled files are put using the `-t` flag, followed
120-
by a directory.
119+
You can control where the compiled files are put using the `-t`/`--output-to`
120+
flag, followed by a directory.
121121

122122
`moonc` can also take a directory as an argument, and it will recursively scan
123123
for all MoonScript files and compile them.
124124

125+
If you use `-t` and also specify a directory as argument, then similar to
126+
`rsync`, handling of whether or not directory names are included in the output
127+
file paths differs depending on whether or not you specify a trailing `/`.
128+
129+
For example, if you have a folder called `src` containing a file `foo.moon`:
130+
131+
```bash
132+
$ moonc -t out src
133+
```
134+
135+
Produces the file `out/src/foo.lua`. Alternatively:
136+
137+
```bash
138+
$ moonc -t out src/
139+
```
140+
141+
Produces the file `out/foo.lua`. It does not matter whether or not there is a
142+
trailing `/` on the `--output-to` directory, only on each of the input
143+
directories specified.
144+
125145
`moonc` can write to standard out by passing the `-p` flag.
126146

127147
The `-w` flag can be used to enable watch mode. `moonc` will stay running, and
128148
watch for changes to the input files. If any of them change then they will be
129-
compiled automatically.
149+
compiled automatically. Watch mode also works in combination with the `-t`
150+
flag.
130151

131152
A full list of flags can be seen by passing the `-h` or `--help` flag.
132153

moonscript-dev-1.rockspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ build = {
3030
["moonscript.cmd.coverage"] = "moonscript/cmd/coverage.lua",
3131
["moonscript.cmd.lint"] = "moonscript/cmd/lint.lua",
3232
["moonscript.cmd.moonc"] = "moonscript/cmd/moonc.lua",
33+
["moonscript.cmd.path_handling"] = "moonscript/cmd/path_handling.lua",
3334
["moonscript.cmd.watchers"] = "moonscript/cmd/watchers.lua",
3435
["moonscript.compile"] = "moonscript/compile.lua",
3536
["moonscript.compile.statement"] = "moonscript/compile/statement.lua",

moonscript/cmd/moonc.lua

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -134,43 +134,52 @@ handle_watch_loop = function(opts, output_to, input_paths, prefix_map)
134134
end
135135
end
136136
end
137-
local watcher = create_watcher(input_paths)
138-
for filename in watcher do
139-
local target = output_for(output_to, prefix_map, filename, "file")
137+
local watcher = create_watcher(output_to, input_paths, prefix_map)
138+
for file_tuple in watcher do
139+
local event_type, filename, target, path_type
140+
event_type, filename, target, path_type = file_tuple[1], file_tuple[2], file_tuple[3], file_tuple[4]
140141
if opts.o then
141142
target = opts.o
142143
end
143144
if opts.lint then
144-
local lint = require("moonscript.cmd.lint")
145-
local success, err = lint.lint_file(filename)
146-
if success then
147-
io.stderr:write(success .. "\n\n")
148-
elseif err then
149-
io.stderr:write(filename .. "\n" .. err .. "\n\n")
145+
if event_type == "changedfile" then
146+
local lint = require("moonscript.cmd.lint")
147+
local success, err = lint.lint_file(filename)
148+
if success then
149+
io.stderr:write(success .. "\n\n")
150+
elseif err then
151+
io.stderr:write(filename .. "\n" .. err .. "\n\n")
152+
end
153+
elseif event_type == "removed" then
154+
remove_orphaned_output(target, path_type)
150155
end
151156
else
152-
local success, err = compile_and_write(filename, target)
153-
if not success then
154-
io.stderr:write(table.concat({
155-
"",
156-
"Error: " .. filename,
157-
err,
158-
"\n"
159-
}, "\n"))
160-
elseif success == "build" then
161-
log_msg("Built", filename, "->", target)
157+
if event_type == "changedfile" then
158+
local success, err = compile_and_write(filename, target)
159+
if not success then
160+
io.stderr:write(table.concat({
161+
"",
162+
"Error: " .. filename,
163+
err,
164+
"\n"
165+
}, "\n"))
166+
elseif success == "build" then
167+
log_msg("Built", filename, "->", target)
168+
end
169+
elseif event_type == "removed" then
170+
remove_orphaned_output(target, path_type)
162171
end
163172
end
164173
end
165174
return io.stderr:write("\nQuitting...\n")
166175
end
167-
create_watcher = function(input_paths)
176+
create_watcher = function(output_to, input_paths, prefix_map)
168177
local watchers = require("moonscript.cmd.watchers")
169178
local watcher
170179
if watchers.InotifyWatcher:available() then
171-
watcher = watchers.InotifyWatcher(input_paths)
180+
watcher = watchers.InotifyWatcher(output_to, input_paths, prefix_map)
172181
else
173-
watcher = watchers.SleepWatcher(input_paths)
182+
watcher = watchers.SleepWatcher(output_to, input_paths, prefix_map)
174183
end
175184
return watcher:each_update()
176185
end

moonscript/cmd/moonc.moon

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -126,44 +126,50 @@ handle_watch_loop = (opts, output_to, input_paths, prefix_map) ->
126126
else
127127
log_msg "Error removing file", target, err_string
128128

129-
watcher = create_watcher input_paths
129+
watcher = create_watcher output_to, input_paths, prefix_map
130130

131-
for filename in watcher
132-
target = output_for(output_to, prefix_map, filename, "file")
131+
for file_tuple in watcher
132+
{event_type, filename, target, path_type} = file_tuple
133133

134134
if opts.o
135135
target = opts.o
136136

137137
if opts.lint
138-
lint = require "moonscript.cmd.lint"
139-
success, err = lint.lint_file filename
140-
if success
141-
io.stderr\write success .. "\n\n"
142-
elseif err
143-
io.stderr\write filename .. "\n" .. err .. "\n\n"
138+
if event_type == "changedfile"
139+
lint = require "moonscript.cmd.lint"
140+
success, err = lint.lint_file filename
141+
if success
142+
io.stderr\write success .. "\n\n"
143+
elseif err
144+
io.stderr\write filename .. "\n" .. err .. "\n\n"
145+
elseif event_type == "removed"
146+
remove_orphaned_output target, path_type
144147
else
145-
success, err = compile_and_write filename, target
146-
if not success
147-
io.stderr\write table.concat({
148-
"",
149-
"Error: " .. filename,
150-
err,
151-
"\n",
152-
}, "\n")
153-
elseif success == "build"
154-
log_msg "Built", filename, "->", target
148+
if event_type == "changedfile"
149+
success, err = compile_and_write filename, target
150+
if not success
151+
io.stderr\write table.concat({
152+
"",
153+
"Error: " .. filename,
154+
err,
155+
"\n",
156+
}, "\n")
157+
elseif success == "build"
158+
log_msg "Built", filename, "->", target
159+
elseif event_type == "removed"
160+
remove_orphaned_output target, path_type
155161

156162
io.stderr\write "\nQuitting...\n"
157163

158-
create_watcher = (input_paths) ->
164+
create_watcher = (output_to, input_paths, prefix_map) ->
159165
watchers = require "moonscript.cmd.watchers"
160166

161167
-- TODO cli argument to force sleep watcher (as it is potentially a little
162168
-- more reliable)
163169
watcher = if watchers.InotifyWatcher\available!
164-
watchers.InotifyWatcher input_paths
170+
watchers.InotifyWatcher output_to, input_paths, prefix_map
165171
else
166-
watchers.SleepWatcher input_paths
172+
watchers.SleepWatcher output_to, input_paths, prefix_map
167173

168174
return watcher\each_update!
169175

0 commit comments

Comments
 (0)