clone url: git://git.m455.casa/fa
esperbuild/esper
1 | #!/usr/bin/env lua5.3 |
2 | -- Author: Will Sinatra <wpsinatra@gmail.com> | License: GPLv3 |
3 | local lume = nil |
4 | package.preload["lume"] = package.preload["lume"] or function(...) |
5 | -- |
6 | -- lume |
7 | -- |
8 | -- Copyright (c) 2017 rxi |
9 | -- |
10 | -- This library is free software; you can redistribute it and/or modify it |
11 | -- under the terms of the MIT license. See LICENSE for details. |
12 | -- |
13 | |
14 | local lume = { _version = "2.3.0" } |
15 | |
16 | local pairs, ipairs = pairs, ipairs |
17 | local type, assert, unpack = type, assert, unpack or table.unpack |
18 | local tostring, tonumber = tostring, tonumber |
19 | local math_floor = math.floor |
20 | local math_ceil = math.ceil |
21 | local math_atan2 = math.atan2 or math.atan |
22 | local math_sqrt = math.sqrt |
23 | local math_abs = math.abs |
24 | |
25 | local noop = function() |
26 | end |
27 | |
28 | local identity = function(x) |
29 | return x |
30 | end |
31 | |
32 | local patternescape = function(str) |
33 | return str:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%1") |
34 | end |
35 | |
36 | local absindex = function(len, i) |
37 | return i < 0 and (len + i + 1) or i |
38 | end |
39 | |
40 | local iscallable = function(x) |
41 | if type(x) == "function" then return true end |
42 | local mt = getmetatable(x) |
43 | return mt and mt.__call ~= nil |
44 | end |
45 | |
46 | local getiter = function(x) |
47 | if lume.isarray(x) then |
48 | return ipairs |
49 | elseif type(x) == "table" then |
50 | return pairs |
51 | end |
52 | error("expected table", 3) |
53 | end |
54 | |
55 | local iteratee = function(x) |
56 | if x == nil then return identity end |
57 | if iscallable(x) then return x end |
58 | if type(x) == "table" then |
59 | return function(z) |
60 | for k, v in pairs(x) do |
61 | if z[k] ~= v then return false end |
62 | end |
63 | return true |
64 | end |
65 | end |
66 | return function(z) return z[x] end |
67 | end |
68 | |
69 | |
70 | |
71 | function lume.clamp(x, min, max) |
72 | return x < min and min or (x > max and max or x) |
73 | end |
74 | |
75 | |
76 | function lume.round(x, increment) |
77 | if increment then return lume.round(x / increment) * increment end |
78 | return x >= 0 and math_floor(x + .5) or math_ceil(x - .5) |
79 | end |
80 | |
81 | |
82 | function lume.sign(x) |
83 | return x < 0 and -1 or 1 |
84 | end |
85 | |
86 | |
87 | function lume.lerp(a, b, amount) |
88 | return a + (b - a) * lume.clamp(amount, 0, 1) |
89 | end |
90 | |
91 | |
92 | function lume.smooth(a, b, amount) |
93 | local t = lume.clamp(amount, 0, 1) |
94 | local m = t * t * (3 - 2 * t) |
95 | return a + (b - a) * m |
96 | end |
97 | |
98 | |
99 | function lume.pingpong(x) |
100 | return 1 - math_abs(1 - x % 2) |
101 | end |
102 | |
103 | |
104 | function lume.distance(x1, y1, x2, y2, squared) |
105 | local dx = x1 - x2 |
106 | local dy = y1 - y2 |
107 | local s = dx * dx + dy * dy |
108 | return squared and s or math_sqrt(s) |
109 | end |
110 | |
111 | |
112 | function lume.angle(x1, y1, x2, y2) |
113 | return math_atan2(y2 - y1, x2 - x1) |
114 | end |
115 | |
116 | |
117 | function lume.vector(angle, magnitude) |
118 | return math.cos(angle) * magnitude, math.sin(angle) * magnitude |
119 | end |
120 | |
121 | |
122 | function lume.random(a, b) |
123 | if not a then a, b = 0, 1 end |
124 | if not b then b = 0 end |
125 | return a + math.random() * (b - a) |
126 | end |
127 | |
128 | |
129 | function lume.randomchoice(t) |
130 | return t[math.random(#t)] |
131 | end |
132 | |
133 | |
134 | function lume.weightedchoice(t) |
135 | local sum = 0 |
136 | for _, v in pairs(t) do |
137 | assert(v >= 0, "weight value less than zero") |
138 | sum = sum + v |
139 | end |
140 | assert(sum ~= 0, "all weights are zero") |
141 | local rnd = lume.random(sum) |
142 | for k, v in pairs(t) do |
143 | if rnd < v then return k end |
144 | rnd = rnd - v |
145 | end |
146 | end |
147 | |
148 | |
149 | function lume.isarray(x) |
150 | return (type(x) == "table" and x[1] ~= nil) and true or false |
151 | end |
152 | |
153 | |
154 | function lume.push(t, ...) |
155 | local n = select("#", ...) |
156 | for i = 1, n do |
157 | t[#t + 1] = select(i, ...) |
158 | end |
159 | return ... |
160 | end |
161 | |
162 | |
163 | function lume.remove(t, x) |
164 | local iter = getiter(t) |
165 | for i, v in iter(t) do |
166 | if v == x then |
167 | if lume.isarray(t) then |
168 | table.remove(t, i) |
169 | break |
170 | else |
171 | t[i] = nil |
172 | break |
173 | end |
174 | end |
175 | end |
176 | return x |
177 | end |
178 | |
179 | |
180 | function lume.clear(t) |
181 | local iter = getiter(t) |
182 | for k in iter(t) do |
183 | t[k] = nil |
184 | end |
185 | return t |
186 | end |
187 | |
188 | |
189 | function lume.extend(t, ...) |
190 | for i = 1, select("#", ...) do |
191 | local x = select(i, ...) |
192 | if x then |
193 | for k, v in pairs(x) do |
194 | t[k] = v |
195 | end |
196 | end |
197 | end |
198 | return t |
199 | end |
200 | |
201 | |
202 | function lume.shuffle(t) |
203 | local rtn = {} |
204 | for i = 1, #t do |
205 | local r = math.random(i) |
206 | if r ~= i then |
207 | rtn[i] = rtn[r] |
208 | end |
209 | rtn[r] = t[i] |
210 | end |
211 | return rtn |
212 | end |
213 | |
214 | |
215 | function lume.sort(t, comp) |
216 | local rtn = lume.clone(t) |
217 | if comp then |
218 | if type(comp) == "string" then |
219 | table.sort(rtn, function(a, b) return a[comp] < b[comp] end) |
220 | else |
221 | table.sort(rtn, comp) |
222 | end |
223 | else |
224 | table.sort(rtn) |
225 | end |
226 | return rtn |
227 | end |
228 | |
229 | |
230 | function lume.array(...) |
231 | local t = {} |
232 | for x in ... do t[#t + 1] = x end |
233 | return t |
234 | end |
235 | |
236 | |
237 | function lume.each(t, fn, ...) |
238 | local iter = getiter(t) |
239 | if type(fn) == "string" then |
240 | for _, v in iter(t) do v[fn](v, ...) end |
241 | else |
242 | for _, v in iter(t) do fn(v, ...) end |
243 | end |
244 | return t |
245 | end |
246 | |
247 | |
248 | function lume.map(t, fn) |
249 | fn = iteratee(fn) |
250 | local iter = getiter(t) |
251 | local rtn = {} |
252 | for k, v in iter(t) do rtn[k] = fn(v) end |
253 | return rtn |
254 | end |
255 | |
256 | |
257 | function lume.all(t, fn) |
258 | fn = iteratee(fn) |
259 | local iter = getiter(t) |
260 | for _, v in iter(t) do |
261 | if not fn(v) then return false end |
262 | end |
263 | return true |
264 | end |
265 | |
266 | |
267 | function lume.any(t, fn) |
268 | fn = iteratee(fn) |
269 | local iter = getiter(t) |
270 | for _, v in iter(t) do |
271 | if fn(v) then return true end |
272 | end |
273 | return false |
274 | end |
275 | |
276 | |
277 | function lume.reduce(t, fn, first) |
278 | local acc = first |
279 | local started = first and true or false |
280 | local iter = getiter(t) |
281 | for _, v in iter(t) do |
282 | if started then |
283 | acc = fn(acc, v) |
284 | else |
285 | acc = v |
286 | started = true |
287 | end |
288 | end |
289 | assert(started, "reduce of an empty table with no first value") |
290 | return acc |
291 | end |
292 | |
293 | |
294 | function lume.set(t) |
295 | local rtn = {} |
296 | for k in pairs(lume.invert(t)) do |
297 | rtn[#rtn + 1] = k |
298 | end |
299 | return rtn |
300 | end |
301 | |
302 | |
303 | function lume.filter(t, fn, retainkeys) |
304 | fn = iteratee(fn) |
305 | local iter = getiter(t) |
306 | local rtn = {} |
307 | if retainkeys then |
308 | for k, v in iter(t) do |
309 | if fn(v) then rtn[k] = v end |
310 | end |
311 | else |
312 | for _, v in iter(t) do |
313 | if fn(v) then rtn[#rtn + 1] = v end |
314 | end |
315 | end |
316 | return rtn |
317 | end |
318 | |
319 | |
320 | function lume.reject(t, fn, retainkeys) |
321 | fn = iteratee(fn) |
322 | local iter = getiter(t) |
323 | local rtn = {} |
324 | if retainkeys then |
325 | for k, v in iter(t) do |
326 | if not fn(v) then rtn[k] = v end |
327 | end |
328 | else |
329 | for _, v in iter(t) do |
330 | if not fn(v) then rtn[#rtn + 1] = v end |
331 | end |
332 | end |
333 | return rtn |
334 | end |
335 | |
336 | |
337 | function lume.merge(...) |
338 | local rtn = {} |
339 | for i = 1, select("#", ...) do |
340 | local t = select(i, ...) |
341 | local iter = getiter(t) |
342 | for k, v in iter(t) do |
343 | rtn[k] = v |
344 | end |
345 | end |
346 | return rtn |
347 | end |
348 | |
349 | |
350 | function lume.concat(...) |
351 | local rtn = {} |
352 | for i = 1, select("#", ...) do |
353 | local t = select(i, ...) |
354 | if t ~= nil then |
355 | local iter = getiter(t) |
356 | for _, v in iter(t) do |
357 | rtn[#rtn + 1] = v |
358 | end |
359 | end |
360 | end |
361 | return rtn |
362 | end |
363 | |
364 | |
365 | function lume.find(t, value) |
366 | local iter = getiter(t) |
367 | for k, v in iter(t) do |
368 | if v == value then return k end |
369 | end |
370 | return nil |
371 | end |
372 | |
373 | |
374 | function lume.match(t, fn) |
375 | fn = iteratee(fn) |
376 | local iter = getiter(t) |
377 | for k, v in iter(t) do |
378 | if fn(v) then return v, k end |
379 | end |
380 | return nil |
381 | end |
382 | |
383 | |
384 | function lume.count(t, fn) |
385 | local count = 0 |
386 | local iter = getiter(t) |
387 | if fn then |
388 | fn = iteratee(fn) |
389 | for _, v in iter(t) do |
390 | if fn(v) then count = count + 1 end |
391 | end |
392 | else |
393 | if lume.isarray(t) then |
394 | return #t |
395 | end |
396 | for _ in iter(t) do count = count + 1 end |
397 | end |
398 | return count |
399 | end |
400 | |
401 | |
402 | function lume.slice(t, i, j) |
403 | i = i and absindex(#t, i) or 1 |
404 | j = j and absindex(#t, j) or #t |
405 | local rtn = {} |
406 | for x = i < 1 and 1 or i, j > #t and #t or j do |
407 | rtn[#rtn + 1] = t[x] |
408 | end |
409 | return rtn |
410 | end |
411 | |
412 | |
413 | function lume.first(t, n) |
414 | if not n then return t[1] end |
415 | return lume.slice(t, 1, n) |
416 | end |
417 | |
418 | |
419 | function lume.last(t, n) |
420 | if not n then return t[#t] end |
421 | return lume.slice(t, -n, -1) |
422 | end |
423 | |
424 | |
425 | function lume.invert(t) |
426 | local rtn = {} |
427 | for k, v in pairs(t) do rtn[v] = k end |
428 | return rtn |
429 | end |
430 | |
431 | |
432 | function lume.pick(t, ...) |
433 | local rtn = {} |
434 | for i = 1, select("#", ...) do |
435 | local k = select(i, ...) |
436 | rtn[k] = t[k] |
437 | end |
438 | return rtn |
439 | end |
440 | |
441 | |
442 | function lume.keys(t) |
443 | local rtn = {} |
444 | local iter = getiter(t) |
445 | for k in iter(t) do rtn[#rtn + 1] = k end |
446 | return rtn |
447 | end |
448 | |
449 | |
450 | function lume.clone(t) |
451 | local rtn = {} |
452 | for k, v in pairs(t) do rtn[k] = v end |
453 | return rtn |
454 | end |
455 | |
456 | |
457 | function lume.fn(fn, ...) |
458 | assert(iscallable(fn), "expected a function as the first argument") |
459 | local args = { ... } |
460 | return function(...) |
461 | local a = lume.concat(args, { ... }) |
462 | return fn(unpack(a)) |
463 | end |
464 | end |
465 | |
466 | |
467 | function lume.once(fn, ...) |
468 | local f = lume.fn(fn, ...) |
469 | local done = false |
470 | return function(...) |
471 | if done then return end |
472 | done = true |
473 | return f(...) |
474 | end |
475 | end |
476 | |
477 | |
478 | local memoize_fnkey = {} |
479 | local memoize_nil = {} |
480 | |
481 | function lume.memoize(fn) |
482 | local cache = {} |
483 | return function(...) |
484 | local c = cache |
485 | for i = 1, select("#", ...) do |
486 | local a = select(i, ...) or memoize_nil |
487 | c[a] = c[a] or {} |
488 | c = c[a] |
489 | end |
490 | c[memoize_fnkey] = c[memoize_fnkey] or {fn(...)} |
491 | return unpack(c[memoize_fnkey]) |
492 | end |
493 | end |
494 | |
495 | |
496 | function lume.combine(...) |
497 | local n = select('#', ...) |
498 | if n == 0 then return noop end |
499 | if n == 1 then |
500 | local fn = select(1, ...) |
501 | if not fn then return noop end |
502 | assert(iscallable(fn), "expected a function or nil") |
503 | return fn |
504 | end |
505 | local funcs = {} |
506 | for i = 1, n do |
507 | local fn = select(i, ...) |
508 | if fn ~= nil then |
509 | assert(iscallable(fn), "expected a function or nil") |
510 | funcs[#funcs + 1] = fn |
511 | end |
512 | end |
513 | return function(...) |
514 | for _, f in ipairs(funcs) do f(...) end |
515 | end |
516 | end |
517 | |
518 | |
519 | function lume.call(fn, ...) |
520 | if fn then |
521 | return fn(...) |
522 | end |
523 | end |
524 | |
525 | |
526 | function lume.time(fn, ...) |
527 | local start = os.clock() |
528 | local rtn = {fn(...)} |
529 | return (os.clock() - start), unpack(rtn) |
530 | end |
531 | |
532 | |
533 | local lambda_cache = {} |
534 | |
535 | function lume.lambda(str) |
536 | if not lambda_cache[str] then |
537 | local args, body = str:match([[^([%w,_ ]-)%->(.-)$]]) |
538 | assert(args and body, "bad string lambda") |
539 | local s = "return function(" .. args .. ")\nreturn " .. body .. "\nend" |
540 | lambda_cache[str] = lume.dostring(s) |
541 | end |
542 | return lambda_cache[str] |
543 | end |
544 | |
545 | |
546 | local serialize |
547 | |
548 | local serialize_map = { |
549 | [ "boolean" ] = tostring, |
550 | [ "nil" ] = tostring, |
551 | [ "string" ] = function(v) return string.format("%q", v) end, |
552 | [ "number" ] = function(v) |
553 | if v ~= v then return "0/0" -- nan |
554 | elseif v == 1 / 0 then return "1/0" -- inf |
555 | elseif v == -1 / 0 then return "-1/0" end -- -inf |
556 | return tostring(v) |
557 | end, |
558 | [ "table" ] = function(t, stk) |
559 | stk = stk or {} |
560 | if stk[t] then error("circular reference") end |
561 | local rtn = {} |
562 | stk[t] = true |
563 | for k, v in pairs(t) do |
564 | rtn[#rtn + 1] = "[" .. serialize(k, stk) .. "]=" .. serialize(v, stk) |
565 | end |
566 | stk[t] = nil |
567 | return "{" .. table.concat(rtn, ",") .. "}" |
568 | end |
569 | } |
570 | |
571 | setmetatable(serialize_map, { |
572 | __index = function(_, k) error("unsupported serialize type: " .. k) end |
573 | }) |
574 | |
575 | serialize = function(x, stk) |
576 | return serialize_map[type(x)](x, stk) |
577 | end |
578 | |
579 | function lume.serialize(x) |
580 | return serialize(x) |
581 | end |
582 | |
583 | |
584 | function lume.deserialize(str) |
585 | return lume.dostring("return " .. str) |
586 | end |
587 | |
588 | |
589 | function lume.split(str, sep) |
590 | if not sep then |
591 | return lume.array(str:gmatch("([%S]+)")) |
592 | else |
593 | assert(sep ~= "", "empty separator") |
594 | local psep = patternescape(sep) |
595 | return lume.array((str..sep):gmatch("(.-)("..psep..")")) |
596 | end |
597 | end |
598 | |
599 | |
600 | function lume.trim(str, chars) |
601 | if not chars then return str:match("^[%s]*(.-)[%s]*$") end |
602 | chars = patternescape(chars) |
603 | return str:match("^[" .. chars .. "]*(.-)[" .. chars .. "]*$") |
604 | end |
605 | |
606 | |
607 | function lume.wordwrap(str, limit) |
608 | limit = limit or 72 |
609 | local check |
610 | if type(limit) == "number" then |
611 | check = function(s) return #s >= limit end |
612 | else |
613 | check = limit |
614 | end |
615 | local rtn = {} |
616 | local line = "" |
617 | for word, spaces in str:gmatch("(%S+)(%s*)") do |
618 | local s = line .. word |
619 | if check(s) then |
620 | table.insert(rtn, line .. "\n") |
621 | line = word |
622 | else |
623 | line = s |
624 | end |
625 | for c in spaces:gmatch(".") do |
626 | if c == "\n" then |
627 | table.insert(rtn, line .. "\n") |
628 | line = "" |
629 | else |
630 | line = line .. c |
631 | end |
632 | end |
633 | end |
634 | table.insert(rtn, line) |
635 | return table.concat(rtn) |
636 | end |
637 | |
638 | |
639 | function lume.format(str, vars) |
640 | if not vars then return str end |
641 | local f = function(x) |
642 | return tostring(vars[x] or vars[tonumber(x)] or "{" .. x .. "}") |
643 | end |
644 | return (str:gsub("{(.-)}", f)) |
645 | end |
646 | |
647 | |
648 | function lume.trace(...) |
649 | local info = debug.getinfo(2, "Sl") |
650 | local t = { info.short_src .. ":" .. info.currentline .. ":" } |
651 | for i = 1, select("#", ...) do |
652 | local x = select(i, ...) |
653 | if type(x) == "number" then |
654 | x = string.format("%g", lume.round(x, .01)) |
655 | end |
656 | t[#t + 1] = tostring(x) |
657 | end |
658 | print(table.concat(t, " ")) |
659 | end |
660 | |
661 | |
662 | function lume.dostring(str) |
663 | return assert((loadstring or load)(str))() |
664 | end |
665 | |
666 | |
667 | function lume.uuid() |
668 | local fn = function(x) |
669 | local r = math.random(16) - 1 |
670 | r = (x == "x") and (r + 1) or (r % 4) + 9 |
671 | return ("0123456789abcdef"):sub(r, r) |
672 | end |
673 | return (("xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"):gsub("[xy]", fn)) |
674 | end |
675 | |
676 | |
677 | function lume.hotswap(modname) |
678 | local oldglobal = lume.clone(_G) |
679 | local updated = {} |
680 | local function update(old, new) |
681 | if updated[old] then return end |
682 | updated[old] = true |
683 | local oldmt, newmt = getmetatable(old), getmetatable(new) |
684 | if oldmt and newmt then update(oldmt, newmt) end |
685 | for k, v in pairs(new) do |
686 | if type(v) == "table" then update(old[k], v) else old[k] = v end |
687 | end |
688 | end |
689 | local err = nil |
690 | local function onerror(e) |
691 | for k in pairs(_G) do _G[k] = oldglobal[k] end |
692 | err = lume.trim(e) |
693 | end |
694 | local ok, oldmod = pcall(require, modname) |
695 | oldmod = ok and oldmod or nil |
696 | xpcall(function() |
697 | package.loaded[modname] = nil |
698 | local newmod = require(modname) |
699 | if type(oldmod) == "table" then update(oldmod, newmod) end |
700 | for k, v in pairs(oldglobal) do |
701 | if v ~= _G[k] and type(v) == "table" then |
702 | update(v, _G[k]) |
703 | _G[k] = v |
704 | end |
705 | end |
706 | end, onerror) |
707 | package.loaded[modname] = oldmod |
708 | if err then return nil, err end |
709 | return oldmod |
710 | end |
711 | |
712 | |
713 | local ripairs_iter = function(t, i) |
714 | i = i - 1 |
715 | local v = t[i] |
716 | if v then return i, v end |
717 | end |
718 | |
719 | function lume.ripairs(t) |
720 | return ripairs_iter, t, (#t + 1) |
721 | end |
722 | |
723 | |
724 | function lume.color(str, mul) |
725 | mul = mul or 1 |
726 | local r, g, b, a |
727 | r, g, b = str:match("#(%x%x)(%x%x)(%x%x)") |
728 | if r then |
729 | r = tonumber(r, 16) / 0xff |
730 | g = tonumber(g, 16) / 0xff |
731 | b = tonumber(b, 16) / 0xff |
732 | a = 1 |
733 | elseif str:match("rgba?%s*%([%d%s%.,]+%)") then |
734 | local f = str:gmatch("[%d.]+") |
735 | r = (f() or 0) / 0xff |
736 | g = (f() or 0) / 0xff |
737 | b = (f() or 0) / 0xff |
738 | a = f() or 1 |
739 | else |
740 | error(("bad color string '%s'"):format(str)) |
741 | end |
742 | return r * mul, g * mul, b * mul, a * mul |
743 | end |
744 | |
745 | |
746 | function lume.rgba(color) |
747 | local a = math_floor((color / 16777216) % 256) |
748 | local r = math_floor((color / 65536) % 256) |
749 | local g = math_floor((color / 256) % 256) |
750 | local b = math_floor((color) % 256) |
751 | return r, g, b, a |
752 | end |
753 | |
754 | |
755 | local chain_mt = {} |
756 | chain_mt.__index = lume.map(lume.filter(lume, iscallable, true), |
757 | function(fn) |
758 | return function(self, ...) |
759 | self._value = fn(self._value, ...) |
760 | return self |
761 | end |
762 | end) |
763 | chain_mt.__index.result = function(x) return x._value end |
764 | |
765 | function lume.chain(value) |
766 | return setmetatable({ _value = value }, chain_mt) |
767 | end |
768 | |
769 | setmetatable(lume, { |
770 | __call = function(_, ...) |
771 | return lume.chain(...) |
772 | end |
773 | }) |
774 | |
775 | |
776 | return lume |
777 | end |
778 | lume = require("lume") |
779 | local bindir = "~/bin/" |
780 | local builddir = "" |
781 | local srcdir = "" |
782 | local espertbl = {} |
783 | local function fetch(tbl) |
784 | local warg = "" |
785 | local outf = tbl.outf |
786 | local at = tbl.at |
787 | local git = tbl.git |
788 | local url = tbl.url |
789 | local extract = tbl.extract |
790 | local typ = tbl.atype |
791 | if ((url == nil) and (at == nil)) then |
792 | print("fetch requires a url or at arg!") |
793 | os.exit() |
794 | end |
795 | if (url ~= nil) then |
796 | if ((git == "") or (git == nil)) then |
797 | if (outf == "") then |
798 | do local _ = (outf == nil) end |
799 | else |
800 | warg = ("wget -O " .. url) |
801 | end |
802 | elseif (git == true) then |
803 | warg = ("git clone " .. url) |
804 | else |
805 | warg = ("wget " .. url .. " -O " .. outf) |
806 | end |
807 | os.execute(("cd " .. srcdir .. " && " .. warg)) |
808 | end |
809 | if (at ~= nil) then |
810 | if (extract == true) then |
811 | os.execute(("cp " .. at .. " " .. srcdir .. "/" .. outf)) |
812 | else |
813 | os.execute(("cp -r " .. at .. " " .. srcdir)) |
814 | end |
815 | end |
816 | if (extract == true) then |
817 | if (typ == "gzip") then |
818 | return os.execute(("cd " .. srcdir .. " && tar -xvzf " .. outf)) |
819 | elseif (typ == "bzip2") then |
820 | return os.execute(("cd " .. srcdir .. " && tar -xvjf " .. outf)) |
821 | elseif (typ == "zip") then |
822 | return os.execute(("cd " .. srcdir .. " && unzip " .. outf)) |
823 | end |
824 | end |
825 | end |
826 | local function prepare() |
827 | local pw = io.popen("pwd") |
828 | local pw0 = pw:read("*a") |
829 | local pw1 = string.gsub(pw0, "[\13\n]", "") |
830 | local src = (pw1 .. "/espersrc") |
831 | srcdir = src |
832 | return os.execute(("mkdir " .. src)) |
833 | end |
834 | local function cleanup() |
835 | if (espertbl.debug == true) then |
836 | return nil |
837 | else |
838 | return os.execute(("rm -rf " .. srcdir)) |
839 | end |
840 | end |
841 | local function ensure(tbl) |
842 | for k, v in pairs(tbl) do |
843 | os.execute(("mkdir -p " .. v)) |
844 | end |
845 | return nil |
846 | end |
847 | local function depends(tbl) |
848 | if (tbl == {}) then |
849 | return print("No depends") |
850 | else |
851 | local distro = io.popen("grep ^ID= /etc/os-release | awk -F'=' '{print $2}'") |
852 | local distro0 = distro:read("*a") |
853 | local distro1 = string.gsub(distro0, "[\13\n]", "") |
854 | if (tbl[distro1] == nil) then |
855 | return print("No depends for target system") |
856 | else |
857 | if ((distro1 == "alpine") or (distro1 == "postmarketos")) then |
858 | return os.execute(("apk -U add " .. tbl.alpine)) |
859 | elseif ((distro1 == "debian") or (distro1 == "ubuntu")) then |
860 | return os.execute(("DEBIAN_FRONTEND=noninteractive apt-get install -y " .. tbl.debian)) |
861 | elseif ((distro1 == "fedora") or (distro1 == "centos") or (distro1 == "rhel")) then |
862 | return os.execute(("yum install -y " .. tbl.rhel)) |
863 | else |
864 | return print("Valid OS types: alpine, debian, rhel") |
865 | end |
866 | end |
867 | end |
868 | end |
869 | local function build(tbl) |
870 | if (tbl == {}) then |
871 | return print("No build defined.") |
872 | else |
873 | builddir = (srcdir .. espertbl.builddir) |
874 | local sh = io.popen("/bin/sh", "w") |
875 | sh:write(("cd " .. builddir .. "\n")) |
876 | for k, v in pairs(tbl) do |
877 | sh:write((v .. "\n")) |
878 | end |
879 | return sh:close() |
880 | end |
881 | end |
882 | local function inst(tbl) |
883 | local installed = "" |
884 | for k, v in pairs(tbl) do |
885 | installed = "" |
886 | local perms = v.perms |
887 | local out = v.out |
888 | local pkgs = v[1] |
889 | for k0, v0 in pairs(pkgs) do |
890 | os.execute(("cd " .. builddir .. " && install -Dm" .. perms .. " " .. v0 .. " " .. out)) |
891 | local i = io.popen(("ls -al " .. out .. " | grep " .. v0)) |
892 | local ir = i:read("*a") |
893 | installed = (installed .. ir) |
894 | end |
895 | print(("The following has been installed to " .. out)) |
896 | print(installed) |
897 | end |
898 | return nil |
899 | end |
900 | local function rename(tbl) |
901 | for k, v in pairs(tbl) do |
902 | local old = v.old |
903 | local new = v.new |
904 | os.execute(("mv " .. builddir .. "/" .. old .. " " .. builddir .. "/" .. new)) |
905 | end |
906 | return nil |
907 | end |
908 | local function esperctrl(ctrl, vargs) |
909 | if (ctrl == "fetch") then |
910 | return fetch(vargs) |
911 | elseif (ctrl == "depends") then |
912 | return depends(vargs) |
913 | elseif (ctrl == "build") then |
914 | return build(vargs) |
915 | elseif (ctrl == "rename") then |
916 | return rename(vargs) |
917 | elseif (ctrl == "inst") then |
918 | return inst(vargs) |
919 | end |
920 | end |
921 | local function init() |
922 | return ensure({"~/bin", "~/.local/share/lua", "~/.local/share/lua/5.3", "~/.local/share/lua/5.2", "~/.local/share/lua/5.1", "~/.local/lib"}) |
923 | end |
924 | local function usage() |
925 | return print("Usage: esper pkg.esper\nAuthor: Durrendal | GPLv3 | v0.1\n\n-h, --help, help - Print this help message\ninit - Create common directories known to Esper") |
926 | end |
927 | local function main(esper) |
928 | if (esper == "init") then |
929 | init() |
930 | os.exit() |
931 | end |
932 | if ((esper == "help") or (esper == "--help") or (esper == "-h") or (esper == nil)) then |
933 | usage() |
934 | os.exit() |
935 | end |
936 | do |
937 | local e = io.open(esper, "r") |
938 | local function close_handlers_0_(ok_0_, ...) |
939 | e:close() |
940 | if ok_0_ then |
941 | return ... |
942 | else |
943 | return error(..., 0) |
944 | end |
945 | end |
946 | local function _2_() |
947 | espertbl = lume.deserialize(e:read("*a")) |
948 | return nil |
949 | end |
950 | close_handlers_0_(xpcall(_2_, (package.loaded.fennel or debug).traceback)) |
951 | end |
952 | prepare() |
953 | if (espertbl.fetch ~= nil) then |
954 | esperctrl("fetch", espertbl.fetch) |
955 | end |
956 | if (espertbl.depends ~= nil) then |
957 | esperctrl("depends", espertbl.depends) |
958 | end |
959 | if (espertbl.build ~= nil) then |
960 | esperctrl("build", espertbl.build) |
961 | end |
962 | if (espertbl.rename ~= nil) then |
963 | esperctrl("rename", espertbl.rename) |
964 | end |
965 | if (espertbl.inst ~= nil) then |
966 | esperctrl("inst", espertbl.inst) |
967 | end |
968 | return cleanup() |
969 | end |
970 | return main(...) |