|
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:option("-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