aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorV1K1NGbg <victor@ilchev.com>2024-07-18 18:44:25 +0300
committerV1K1NGbg <victor@ilchev.com>2024-08-05 20:49:17 +0300
commitabb81d2d72b03321ffda491e99543552121f69e9 (patch)
treed71cde637fa440e8387731e6f7789f99f9a5256d
parente5c279e5ef87ee8ed59a43ca5ea00ce9ecf459f3 (diff)
downloadluarocks-abb81d2d72b03321ffda491e99543552121f69e9.tar.gz
luarocks-abb81d2d72b03321ffda491e99543552121f69e9.tar.bz2
luarocks-abb81d2d72b03321ffda491e99543552121f69e9.zip
something happened
-rw-r--r--src/luarocks/core/persist.tl2
-rw-r--r--src/luarocks/persist-original.lua (renamed from src/luarocks/persist.lua)0
-rw-r--r--src/luarocks/persist.tl261
3 files changed, 262 insertions, 1 deletions
diff --git a/src/luarocks/core/persist.tl b/src/luarocks/core/persist.tl
index f89a95c1..31dfe289 100644
--- a/src/luarocks/core/persist.tl
+++ b/src/luarocks/core/persist.tl
@@ -45,7 +45,7 @@ end
45-- or nil, an error message and an error code ("open"; couldn't open the file, 45-- or nil, an error message and an error code ("open"; couldn't open the file,
46-- "load"; compile-time error, or "run"; run-time error) 46-- "load"; compile-time error, or "run"; run-time error)
47-- in case of errors. 47-- in case of errors.
48function persist.load_into_table(filename: string, tbl: {string:any}) : table, table | string, string 48function persist.load_into_table(filename: string, tbl: {string:any}) : {any: any}, {any: any} | string, string
49 49
50 local result: {string:any} = tbl or {} 50 local result: {string:any} = tbl or {}
51 local globals = {} 51 local globals = {}
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist-original.lua
index 4dcd930a..4dcd930a 100644
--- a/src/luarocks/persist.lua
+++ b/src/luarocks/persist-original.lua
diff --git a/src/luarocks/persist.tl b/src/luarocks/persist.tl
new file mode 100644
index 00000000..5611b684
--- /dev/null
+++ b/src/luarocks/persist.tl
@@ -0,0 +1,261 @@
1
2--- Utility module for loading files into tables and
3-- saving tables into files.
4local record persist
5 run_file: function(string, {string:any}): boolean, any | string, string
6 load_into_table: function(string, {string:any}) : {any: any}, {any: any} | string, string
7end
8
9local core = require("luarocks.core.persist")
10local util = require("luarocks.util")
11local dir = require("luarocks.dir")
12local fs = require("luarocks.fs")
13
14persist.run_file = core.run_file
15persist.load_into_table = core.load_into_table
16
17local write_table: function(out, tbl: {number | string: number| string}, level: integer, field_order: {(number | string): any})
18
19--- Write a value as Lua code.
20-- This function handles only numbers and strings, invoking write_table
21-- to write tables.
22-- @param out table or userdata: a writer object supporting :write() method.
23-- @param v: the value to be written.
24-- @param level number: the indentation level
25-- @param sub_order table: optional prioritization table
26-- @see write_table
27function persist.write_value(out, v: any, level: integer, sub_order) --! out type
28 if v is {any: any} then
29 level = level or 0
30 write_table(out, v, level + 1, sub_order)
31 elseif v is string then
32 if v:match("[\r\n]") then
33 local open, close = "[[", "]]"
34 local equals = 0
35 local v_with_bracket = v.."]"
36 while v_with_bracket:find(close, 1, true) do
37 equals = equals + 1
38 local eqs = ("="):rep(equals)
39 open, close = "["..eqs.."[", "]"..eqs.."]"
40 end
41 out:write(open.."\n"..v..close)
42 else
43 out:write(("%q"):format(v))
44 end
45 else
46 out:write(tostring(v))
47 end
48end
49
50local is_valid_plain_key: function(string): boolean
51do
52 local keywords: {string: boolean} = {
53 ["and"] = true,
54 ["break"] = true,
55 ["do"] = true,
56 ["else"] = true,
57 ["elseif"] = true,
58 ["end"] = true,
59 ["false"] = true,
60 ["for"] = true,
61 ["function"] = true,
62 ["goto"] = true,
63 ["if"] = true,
64 ["in"] = true,
65 ["local"] = true,
66 ["nil"] = true,
67 ["not"] = true,
68 ["or"] = true,
69 ["repeat"] = true,
70 ["return"] = true,
71 ["then"] = true,
72 ["true"] = true,
73 ["until"] = true,
74 ["while"] = true,
75 }
76 function is_valid_plain_key(k: string): boolean
77 return k:match("^[a-zA-Z_][a-zA-Z0-9_]*$")
78 and not keywords[k]
79 end
80end
81
82local function write_table_key_assignment(out, k: string | number, level: integer)
83 if k is string and is_valid_plain_key(k) then
84 out:write(k)
85 else
86 out:write("[")
87 persist.write_value(out, k, level)
88 out:write("]")
89 end
90
91 out:write(" = ")
92end
93
94--- Write a table as Lua code in curly brackets notation to a writer object.
95-- Only numbers, strings and tables (containing numbers, strings
96-- or other recursively processed tables) are supported.
97-- @param out table or userdata: a writer object supporting :write() method.
98-- @param tbl table: the table to be written.
99-- @param level number: the indentation level
100-- @param field_order table: optional prioritization table
101write_table = function(out, tbl: {number | string: number| string}, level: integer, field_order: {(number | string): any}) --? suborrder type?
102 out:write("{")
103 local sep = "\n"
104 local indentation = " "
105 local indent = true
106 local i = 1
107 for k, v, sub_order in util.sortedpairs(tbl, field_order) do
108 out:write(sep)
109 if indent then
110 for _ = 1, level do out:write(indentation) end
111 end
112
113 if k is number then
114 i = i + 1
115 else
116 write_table_key_assignment(out, k, level)
117 end
118
119 persist.write_value(out, v, level, sub_order)
120 if v is number then
121 sep = ", "
122 indent = false
123 else
124 sep = ",\n"
125 indent = true
126 end
127 end
128 if sep ~= "\n" then
129 out:write("\n")
130 for _ = 1, level - 1 do out:write(indentation) end
131 end
132 out:write("}")
133end
134
135--- Write a table as series of assignments to a writer object.
136-- @param out table or userdata: a writer object supporting :write() method.
137-- @param tbl table: the table to be written.
138-- @param field_order table: optional prioritization table
139-- @return true if successful; nil and error message if failed.
140local function write_table_as_assignments(out, tbl, field_order)
141 for k, v, sub_order in util.sortedpairs(tbl, field_order) do
142 if not is_valid_plain_key(k) then
143 return nil, "cannot store '"..tostring(k).."' as a plain key."
144 end
145 out:write(k.." = ")
146 persist.write_value(out, v, 0, sub_order)
147 out:write("\n")
148 end
149 return true
150end
151
152--- Write a table using Lua table syntax to a writer object.
153-- @param out table or userdata: a writer object supporting :write() method.
154-- @param tbl table: the table to be written.
155local function write_table_as_table(out, tbl)
156 out:write("return {\n")
157 for k, v, sub_order in util.sortedpairs(tbl) do
158 out:write(" ")
159 write_table_key_assignment(out, k, 1)
160 persist.write_value(out, v, 1, sub_order)
161 out:write(",\n")
162 end
163 out:write("}\n")
164end
165
166--- Save the contents of a table to a string.
167-- Each element of the table is saved as a global assignment.
168-- Only numbers, strings and tables (containing numbers, strings
169-- or other recursively processed tables) are supported.
170-- @param tbl table: the table containing the data to be written
171-- @param field_order table: an optional array indicating the order of top-level fields.
172-- @return persisted data as string; or nil and an error message
173function persist.save_from_table_to_string(tbl, field_order)
174 local out = {buffer = {}}
175 function out:write(data) table.insert(self.buffer, data) end
176 local ok, err = write_table_as_assignments(out, tbl, field_order)
177 if not ok then
178 return nil, err
179 end
180 return table.concat(out.buffer)
181end
182
183--- Save the contents of a table in a file.
184-- Each element of the table is saved as a global assignment.
185-- Only numbers, strings and tables (containing numbers, strings
186-- or other recursively processed tables) are supported.
187-- @param filename string: the output filename
188-- @param tbl table: the table containing the data to be written
189-- @param field_order table: an optional array indicating the order of top-level fields.
190-- @return boolean or (nil, string): true if successful, or nil and a
191-- message in case of errors.
192function persist.save_from_table(filename, tbl, field_order)
193 local prefix = dir.dir_name(filename)
194 fs.make_dir(prefix)
195 local out = io.open(filename, "w")
196 if not out then
197 return nil, "Cannot create file at "..filename
198 end
199 local ok, err = write_table_as_assignments(out, tbl, field_order)
200 out:close()
201 if not ok then
202 return nil, err
203 end
204 return true
205end
206
207--- Save the contents of a table as a module.
208-- The module contains a 'return' statement that returns the table.
209-- Only numbers, strings and tables (containing numbers, strings
210-- or other recursively processed tables) are supported.
211-- @param filename string: the output filename
212-- @param tbl table: the table containing the data to be written
213-- @return boolean or (nil, string): true if successful, or nil and a
214-- message in case of errors.
215function persist.save_as_module(filename, tbl)
216 local out = io.open(filename, "w")
217 if not out then
218 return nil, "Cannot create file at "..filename
219 end
220 write_table_as_table(out, tbl)
221 out:close()
222 return true
223end
224
225function persist.load_config_file_if_basic(filename, cfg)
226 local env = {
227 home = cfg.home
228 }
229 local result, err, errcode = persist.load_into_table(filename, env)
230 if errcode == "load" or errcode == "run" then
231 -- bad config file or depends on env, so error out
232 return nil, "Could not read existing config file " .. filename
233 end
234
235 local tbl
236 if errcode == "open" then
237 -- could not open, maybe file does not exist
238 tbl = {}
239 else
240 tbl = result
241 tbl.home = nil
242 end
243
244 return tbl
245end
246
247function persist.save_default_lua_version(prefix, lua_version)
248 local ok, err = fs.make_dir(prefix)
249 if not ok then
250 return nil, err
251 end
252 local fd, err = io.open(dir.path(prefix, "default-lua-version.lua"), "w")
253 if not fd then
254 return nil, err
255 end
256 fd:write('return "' .. lua_version .. '"\n')
257 fd:close()
258 return true
259end
260
261return persist