-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpack-front.lua
More file actions
executable file
·124 lines (99 loc) · 2.84 KB
/
pack-front.lua
File metadata and controls
executable file
·124 lines (99 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env tarantool
local log = require('log')
local fio = require('fio')
local ffi = require('ffi')
local json = require('json')
local src_json = arg[1]
local dst_name = arg[2]
if not src_json or not dst_name then
error("Usage: pack.lua SRC.json DST.lua")
end
log.info("-- Cwd %s", fio.cwd())
local abspath = fio.abspath(src_json)
assert(fio.stat(abspath),
('Error: can not pack %q: file does not exist'):format(src_json)
)
log.info('-- Pack %s', abspath)
local f = io.open(abspath, "r")
local body = f:read('*a')
f:close()
local function pack(value)
if type(value) == 'string' then
return string.format('%q', value)
elseif type(value) == 'boolean' then
return tostring(value)
elseif type(value) == 'number' then
return tostring(value)
elseif value == nil then
return 'box.NULL'
elseif type(value) == 'table' then
local ret = {}
for k, v in pairs(value) do
table.insert(ret, string.format("[%s] = %s", pack(k), pack(v)))
end
return string.format('{\n%s\n}', table.concat(ret, ',\n'))
else
error(string.format('Can not pack %s %q', type(value), value))
end
end
local function deepcmp(got, expected, extra)
if extra == nil then
extra = {}
end
if type(expected) == "number" or type(got) == "number" then
extra.got = got
extra.expected = expected
if got ~= got and expected ~= expected then
return true -- nan
end
return got == expected
end
if ffi.istype('bool', got) then got = (got == 1) end
if ffi.istype('bool', expected) then expected = (expected == 1) end
if got == nil and expected == nil then return true end
if type(got) ~= type(expected) then
extra.got = type(got)
extra.expected = type(expected)
return false
end
if type(got) ~= 'table' then
extra.got = got
extra.expected = expected
return got == expected
end
local path = extra.path or '/'
for i, v in pairs(got) do
extra.path = path .. '/' .. i
if not deepcmp(v, expected[i], extra) then
return false
end
end
for i, v in pairs(expected) do
extra.path = path .. '/' .. i
if not deepcmp(got[i], v, extra) then
return false
end
end
extra.path = path
return true
end
local data = json.decode(body)
local mod_str = string.format([[
local data = %s
return {
__data = function()
return data
end
}
]], pack(data))
-- Check that bundling doesn't damage data
do
local mod = assert(loadstring(mod_str, dst_name))()
assert(deepcmp(data, mod.__data()))
end
log.info('-- Save %s', dst_name)
log.info('Total: %.0f KiB', (#mod_str)/1024)
local f = assert(io.open(dst_name, "wb"))
assert(f:write(mod_str))
assert(f:close())
os.exit(0)