|
1 | 1 | #!/usr/bin/env lua |
2 | 2 |
|
3 | | -local argparse = require "argparse" |
4 | | -local lfs = require "lfs" |
5 | | - |
6 | | -local parser = argparse() |
7 | | - |
8 | | -parser:flag("-l --lint", "Perform a lint on the file instead of compiling") |
9 | | -parser:flag("-v --version", "Print version") |
10 | | -parser:flag("-w --watch", "Watch file/directory for updates") |
11 | | -parser:option("--transform", "Transform syntax tree with module") |
12 | | -parser:mutex( |
13 | | - parser:flag("-t --output-to", "Specify where to place compiled files"), |
14 | | - parser:option("-o", "Write output to file"), |
15 | | - parser:flag("-p", "Write output to standard output"), |
16 | | - parser:flag("-T", "Write parse tree instead of code (to stdout)"), |
17 | | - parser:flag("-b", "Write parse and compile time instead of code(to stdout)"), |
18 | | - parser:flag("-X", "Write line rewrite map instead of code (to stdout)") |
19 | | -) |
20 | | -parser:flag("-", |
21 | | - "Read from standard in, print to standard out (Must be only argument)") |
22 | | - |
23 | | -local read_stdin = arg[1] == "--" -- luacheck: ignore 113 |
24 | | - |
25 | | -if not read_stdin then |
26 | | - parser:argument("file/directory"):args("+") |
27 | | -end |
28 | | - |
29 | | -local opts = parser:parse() |
30 | | - |
31 | | -if opts.version then |
32 | | - local v = require "moonscript.version" |
33 | | - v.print_version() |
34 | | - os.exit() |
35 | | -end |
36 | | - |
37 | | -function log_msg(...) |
38 | | - if not opts.p then |
39 | | - io.stderr:write(table.concat({...}, " ") .. "\n") |
40 | | - end |
41 | | -end |
42 | | - |
43 | | -local moonc = require("moonscript.cmd.moonc") |
44 | | -local util = require "moonscript.util" |
45 | | -local normalize_dir = moonc.normalize_dir |
46 | | -local compile_and_write = moonc.compile_and_write |
47 | | -local path_to_target = moonc.path_to_target |
48 | | - |
49 | | -local function scan_directory(root, collected) |
50 | | - root = normalize_dir(root) |
51 | | - collected = collected or {} |
52 | | - |
53 | | - for fname in lfs.dir(root) do |
54 | | - if not fname:match("^%.") then |
55 | | - local full_path = root..fname |
56 | | - |
57 | | - if lfs.attributes(full_path, "mode") == "directory" then |
58 | | - scan_directory(full_path, collected) |
59 | | - elseif fname:match("%.moon$") then |
60 | | - table.insert(collected, full_path) |
61 | | - end |
62 | | - end |
63 | | - end |
64 | | - |
65 | | - return collected |
66 | | -end |
67 | | - |
68 | | -local function remove_dups(tbl, key_fn) |
69 | | - local hash = {} |
70 | | - local final = {} |
71 | | - |
72 | | - for _, v in ipairs(tbl) do |
73 | | - local dup_key = key_fn and key_fn(v) or v |
74 | | - if not hash[dup_key] then |
75 | | - table.insert(final, v) |
76 | | - hash[dup_key] = true |
77 | | - end |
78 | | - end |
79 | | - |
80 | | - return final |
81 | | -end |
82 | | - |
83 | | --- creates tuples of input and target |
84 | | -local function get_files(fname, files) |
85 | | - files = files or {} |
86 | | - |
87 | | - if lfs.attributes(fname, "mode") == "directory" then |
88 | | - for _, sub_fname in ipairs(scan_directory(fname)) do |
89 | | - table.insert(files, { |
90 | | - sub_fname, |
91 | | - path_to_target(sub_fname, opts.output_to, fname) |
92 | | - }) |
93 | | - end |
94 | | - else |
95 | | - table.insert(files, { |
96 | | - fname, |
97 | | - path_to_target(fname, opts.output_to) |
98 | | - }) |
99 | | - end |
100 | | - |
101 | | - return files |
102 | | -end |
103 | | - |
104 | | -if read_stdin then |
105 | | - local parse = require "moonscript.parse" |
106 | | - local compile = require "moonscript.compile" |
107 | | - |
108 | | - local text = io.stdin:read("*a") |
109 | | - local tree, err = parse.string(text) |
110 | | - |
111 | | - if not tree then error(err) end |
112 | | - local code, err, pos = compile.tree(tree) |
113 | | - |
114 | | - if not code then |
115 | | - error(compile.format_error(err, pos, text)) |
116 | | - end |
117 | | - |
118 | | - print(code) |
119 | | - os.exit() |
120 | | -end |
121 | | - |
122 | | -local inputs = opts["file/directory"] |
123 | | - |
124 | | -local files = {} |
125 | | -for _, input in ipairs(inputs) do |
126 | | - get_files(input, files) |
127 | | -end |
128 | | - |
129 | | -files = remove_dups(files, function(f) |
130 | | - return f[2] |
131 | | -end) |
132 | | - |
133 | | --- returns an iterator that returns files that have been updated |
134 | | -local function create_watcher(files) |
135 | | - local watchers = require("moonscript.cmd.watchers") |
136 | | - |
137 | | - if watchers.InotifyWacher:available() then |
138 | | - return watchers.InotifyWacher(files):each_update() |
139 | | - end |
140 | | - |
141 | | - return watchers.SleepWatcher(files):each_update() |
142 | | -end |
143 | | - |
144 | | -if opts.watch then |
145 | | - -- build function to check for lint or compile in watch |
146 | | - local handle_file |
147 | | - if opts.lint then |
148 | | - local lint = require "moonscript.cmd.lint" |
149 | | - handle_file = lint.lint_file |
150 | | - else |
151 | | - handle_file = compile_and_write |
152 | | - end |
153 | | - |
154 | | - local watcher = create_watcher(files) |
155 | | - -- catches interrupt error for ctl-c |
156 | | - local protected = function() |
157 | | - local status, file = true, watcher() |
158 | | - if status then |
159 | | - return file |
160 | | - elseif file ~= "interrupted!" then |
161 | | - error(file) |
162 | | - end |
163 | | - end |
164 | | - |
165 | | - for fname in protected do |
166 | | - local target = path_to_target(fname, opts.output_to) |
167 | | - |
168 | | - if opts.o then |
169 | | - target = opts.o |
170 | | - end |
171 | | - |
172 | | - local success, err = handle_file(fname, target) |
173 | | - if opts.lint then |
174 | | - if success then |
175 | | - io.stderr:write(success .. "\n\n") |
176 | | - elseif err then |
177 | | - io.stderr:write(fname .. "\n" .. err .. "\n\n") |
178 | | - end |
179 | | - elseif not success then |
180 | | - io.stderr:write(table.concat({ |
181 | | - "", |
182 | | - "Error: " .. fname, |
183 | | - err, |
184 | | - "\n", |
185 | | - }, "\n")) |
186 | | - elseif success == "build" then |
187 | | - log_msg("Built", fname, "->", target) |
188 | | - end |
189 | | - end |
190 | | - |
191 | | - io.stderr:write("\nQuitting...\n") |
192 | | -elseif opts.lint then |
193 | | - local has_linted_with_error; |
194 | | - local lint = require "moonscript.cmd.lint" |
195 | | - for _, tuple in pairs(files) do |
196 | | - local fname = tuple[1] |
197 | | - local res, err = lint.lint_file(fname) |
198 | | - if res then |
199 | | - has_linted_with_error = true |
200 | | - io.stderr:write(res .. "\n\n") |
201 | | - elseif err then |
202 | | - has_linted_with_error = true |
203 | | - io.stderr:write(fname .. "\n" .. err.. "\n\n") |
204 | | - end |
205 | | - end |
206 | | - if has_linted_with_error then |
207 | | - os.exit(1) |
208 | | - end |
209 | | -else |
210 | | - for _, tuple in ipairs(files) do |
211 | | - local fname, target = util.unpack(tuple) |
212 | | - if opts.o then |
213 | | - target = opts.o |
214 | | - end |
215 | | - |
216 | | - local success, err = compile_and_write(fname, target, { |
217 | | - print = opts.p, |
218 | | - fname = fname, |
219 | | - benchmark = opts.b, |
220 | | - show_posmap = opts.X, |
221 | | - show_parse_tree = opts.T, |
222 | | - transform_module = opts.transform |
223 | | - }) |
224 | | - |
225 | | - if not success then |
226 | | - io.stderr:write(fname .. "\t" .. err .. "\n") |
227 | | - os.exit(1) |
228 | | - end |
229 | | - end |
230 | | -end |
231 | | - |
232 | | - |
| 3 | +local moonc = require "moonscript.cmd.moonc" |
| 4 | +moonc.main(arg) |
0 commit comments