aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorV1K1NGbg <victor@ilchev.com>2024-08-01 21:30:50 +0300
committerV1K1NGbg <victor@ilchev.com>2024-08-05 20:51:31 +0300
commit470839668f178cf7259648c0f4c296c88570e4db (patch)
tree479523e528cc913f12f412db1aabc1d636de2aea
parent64f6f2a4b9ae1dc44a955013b5a7d240f661aa70 (diff)
downloadluarocks-470839668f178cf7259648c0f4c296c88570e4db.tar.gz
luarocks-470839668f178cf7259648c0f4c296c88570e4db.tar.bz2
luarocks-470839668f178cf7259648c0f4c296c88570e4db.zip
queries
-rw-r--r--src/luarocks/queries-origianl.lua217
-rw-r--r--src/luarocks/queries.lua160
-rw-r--r--src/luarocks/queries.tl35
3 files changed, 324 insertions, 88 deletions
diff --git a/src/luarocks/queries-origianl.lua b/src/luarocks/queries-origianl.lua
new file mode 100644
index 00000000..0c8790fa
--- /dev/null
+++ b/src/luarocks/queries-origianl.lua
@@ -0,0 +1,217 @@
1
2local queries = {}
3
4local vers = require("luarocks.core.vers")
5local util = require("luarocks.util")
6local cfg = require("luarocks.core.cfg")
7
8local query_mt = {}
9
10query_mt.__index = query_mt
11
12function query_mt.type()
13 return "query"
14end
15
16-- Fallback default value for the `arch` field, if not explicitly set.
17query_mt.arch = {
18 src = true,
19 all = true,
20 rockspec = true,
21 installed = true,
22 -- [cfg.arch] = true, -- this is set later
23}
24
25-- Fallback default value for the `substring` field, if not explicitly set.
26query_mt.substring = false
27
28--- Convert the arch field of a query table to table format.
29-- @param input string, table or nil
30local function arch_to_table(input)
31 if type(input) == "table" then
32 return input
33 elseif type(input) == "string" then
34 local arch = {}
35 for a in input:gmatch("[%w_-]+") do
36 arch[a] = true
37 end
38 return arch
39 end
40end
41
42--- Prepare a query in dependency table format.
43-- @param name string: the package name.
44-- @param namespace string?: the package namespace.
45-- @param version string?: the package version.
46-- @param substring boolean?: match substrings of the name
47-- (default is false, match full name)
48-- @param arch string?: a string with pipe-separated accepted arch values
49-- @param operator string?: operator for version matching (default is "==")
50-- @return table: A query in table format
51function queries.new(name, namespace, version, substring, arch, operator)
52 assert(type(name) == "string")
53 assert(type(namespace) == "string" or not namespace)
54 assert(type(version) == "string" or not version)
55 assert(type(substring) == "boolean" or not substring)
56 assert(type(arch) == "string" or not arch)
57 assert(type(operator) == "string" or not operator)
58
59 operator = operator or "=="
60
61 local self = {
62 name = name,
63 namespace = namespace,
64 constraints = {},
65 substring = substring,
66 arch = arch_to_table(arch),
67 }
68 if version then
69 table.insert(self.constraints, { op = operator, version = vers.parse_version(version)})
70 end
71
72 query_mt.arch[cfg.arch] = true
73 return setmetatable(self, query_mt)
74end
75
76-- Query for all packages
77-- @param arch string (optional)
78function queries.all(arch)
79 assert(type(arch) == "string" or not arch)
80
81 return queries.new("", nil, nil, true, arch)
82end
83
84do
85 local parse_constraints
86 do
87 local parse_constraint
88 do
89 local operators = {
90 ["=="] = "==",
91 ["~="] = "~=",
92 [">"] = ">",
93 ["<"] = "<",
94 [">="] = ">=",
95 ["<="] = "<=",
96 ["~>"] = "~>",
97 -- plus some convenience translations
98 [""] = "==",
99 ["="] = "==",
100 ["!="] = "~="
101 }
102
103 --- Consumes a constraint from a string, converting it to table format.
104 -- For example, a string ">= 1.0, > 2.0" is converted to a table in the
105 -- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned
106 -- back to the caller.
107 -- @param input string: A list of constraints in string format.
108 -- @return (table, string) or nil: A table representing the same
109 -- constraints and the string with the unused input, or nil if the
110 -- input string is invalid.
111 parse_constraint = function(input)
112 assert(type(input) == "string")
113
114 local no_upgrade, op, version, rest = input:match("^(@?)([<>=~!]*)%s*([%w%.%_%-]+)[%s,]*(.*)")
115 local _op = operators[op]
116 version = vers.parse_version(version)
117 if not _op then
118 return nil, "Encountered bad constraint operator: '"..tostring(op).."' in '"..input.."'"
119 end
120 if not version then
121 return nil, "Could not parse version from constraint: '"..input.."'"
122 end
123 return { op = _op, version = version, no_upgrade = no_upgrade=="@" and true or nil }, rest
124 end
125 end
126
127 --- Convert a list of constraints from string to table format.
128 -- For example, a string ">= 1.0, < 2.0" is converted to a table in the format
129 -- {{op = ">=", version={1,0}}, {op = "<", version={2,0}}}.
130 -- Version tables use a metatable allowing later comparison through
131 -- relational operators.
132 -- @param input string: A list of constraints in string format.
133 -- @return table or nil: A table representing the same constraints,
134 -- or nil if the input string is invalid.
135 parse_constraints = function(input)
136 assert(type(input) == "string")
137
138 local constraints, oinput, constraint = {}, input
139 while #input > 0 do
140 constraint, input = parse_constraint(input)
141 if constraint then
142 table.insert(constraints, constraint)
143 else
144 return nil, "Failed to parse constraint '"..tostring(oinput).."' with error: ".. input
145 end
146 end
147 return constraints
148 end
149 end
150
151 --- Prepare a query in dependency table format.
152 -- @param depstr string: A dependency in string format
153 -- as entered in rockspec files.
154 -- @return table: A query in table format, or nil and an error message in case of errors.
155 function queries.from_dep_string(depstr)
156 assert(type(depstr) == "string")
157
158 local ns_name, rest = depstr:match("^%s*([a-zA-Z0-9%.%-%_]*/?[a-zA-Z0-9][a-zA-Z0-9%.%-%_]*)%s*([^/]*)")
159 if not ns_name then
160 return nil, "failed to extract dependency name from '"..depstr.."'"
161 end
162
163 ns_name = ns_name:lower()
164
165 local constraints, err = parse_constraints(rest)
166 if not constraints then
167 return nil, err
168 end
169
170 local name, namespace = util.split_namespace(ns_name)
171
172 local self = {
173 name = name,
174 namespace = namespace,
175 constraints = constraints,
176 }
177
178 query_mt.arch[cfg.arch] = true
179 return setmetatable(self, query_mt)
180 end
181end
182
183function queries.from_persisted_table(tbl)
184 query_mt.arch[cfg.arch] = true
185 return setmetatable(tbl, query_mt)
186end
187
188--- Build a string representation of a query package name.
189-- Includes namespace, name and version, but not arch or constraints.
190-- @param query table: a query table
191-- @return string: a result such as `my_user/my_rock 1.0` or `my_rock`.
192function query_mt:__tostring()
193 local out = {}
194 if self.namespace then
195 table.insert(out, self.namespace)
196 table.insert(out, "/")
197 end
198 table.insert(out, self.name)
199
200 if #self.constraints > 0 then
201 local pretty = {}
202 for _, c in ipairs(self.constraints) do
203 local v = c.version.string
204 if c.op == "==" then
205 table.insert(pretty, v)
206 else
207 table.insert(pretty, c.op .. " " .. v)
208 end
209 end
210 table.insert(out, " ")
211 table.insert(out, table.concat(pretty, ", "))
212 end
213
214 return table.concat(out)
215end
216
217return queries
diff --git a/src/luarocks/queries.lua b/src/luarocks/queries.lua
index 0c8790fa..89cd1799 100644
--- a/src/luarocks/queries.lua
+++ b/src/luarocks/queries.lua
@@ -1,32 +1,45 @@
1local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table
2local queries = {Query = {}, }
3
4
5
6
7
8
9
1 10
2local queries = {}
3 11
4local vers = require("luarocks.core.vers") 12local vers = require("luarocks.core.vers")
5local util = require("luarocks.util") 13local util = require("luarocks.util")
6local cfg = require("luarocks.core.cfg") 14local cfg = require("luarocks.core.cfg")
7 15
16
17
18
19
20
8local query_mt = {} 21local query_mt = {}
9 22
10query_mt.__index = query_mt 23query_mt.__index = queries.Query
11 24
12function query_mt.type() 25function queries.Query.type()
13 return "query" 26 return "query"
14end 27end
15 28
16-- Fallback default value for the `arch` field, if not explicitly set. 29
17query_mt.arch = { 30queries.Query.arch = {
18 src = true, 31 src = true,
19 all = true, 32 all = true,
20 rockspec = true, 33 rockspec = true,
21 installed = true, 34 installed = true,
22 -- [cfg.arch] = true, -- this is set later 35
23} 36}
24 37
25-- Fallback default value for the `substring` field, if not explicitly set.
26query_mt.substring = false
27 38
28--- Convert the arch field of a query table to table format. 39queries.Query.substring = false
29-- @param input string, table or nil 40
41
42
30local function arch_to_table(input) 43local function arch_to_table(input)
31 if type(input) == "table" then 44 if type(input) == "table" then
32 return input 45 return input
@@ -39,22 +52,21 @@ local function arch_to_table(input)
39 end 52 end
40end 53end
41 54
42--- Prepare a query in dependency table format. 55
43-- @param name string: the package name. 56
44-- @param namespace string?: the package namespace. 57
45-- @param version string?: the package version. 58
46-- @param substring boolean?: match substrings of the name 59
47-- (default is false, match full name) 60
48-- @param arch string?: a string with pipe-separated accepted arch values 61
49-- @param operator string?: operator for version matching (default is "==") 62
50-- @return table: A query in table format 63
51function queries.new(name, namespace, version, substring, arch, operator) 64function queries.new(name, namespace, version, substring, arch, operator)
52 assert(type(name) == "string") 65
53 assert(type(namespace) == "string" or not namespace) 66
54 assert(type(version) == "string" or not version) 67
55 assert(type(substring) == "boolean" or not substring) 68
56 assert(type(arch) == "string" or not arch) 69
57 assert(type(operator) == "string" or not operator)
58 70
59 operator = operator or "==" 71 operator = operator or "=="
60 72
@@ -66,17 +78,17 @@ function queries.new(name, namespace, version, substring, arch, operator)
66 arch = arch_to_table(arch), 78 arch = arch_to_table(arch),
67 } 79 }
68 if version then 80 if version then
69 table.insert(self.constraints, { op = operator, version = vers.parse_version(version)}) 81 table.insert(self.constraints, { op = operator, version = vers.parse_version(version) })
70 end 82 end
71 83
72 query_mt.arch[cfg.arch] = true 84 queries.Query.arch[cfg.arch] = true
73 return setmetatable(self, query_mt) 85 return setmetatable(self, query_mt)
74end 86end
75 87
76-- Query for all packages 88
77-- @param arch string (optional) 89
78function queries.all(arch) 90function queries.all(arch)
79 assert(type(arch) == "string" or not arch) 91
80 92
81 return queries.new("", nil, nil, true, arch) 93 return queries.new("", nil, nil, true, arch)
82end 94end
@@ -94,70 +106,68 @@ do
94 [">="] = ">=", 106 [">="] = ">=",
95 ["<="] = "<=", 107 ["<="] = "<=",
96 ["~>"] = "~>", 108 ["~>"] = "~>",
97 -- plus some convenience translations 109
98 [""] = "==", 110 [""] = "==",
99 ["="] = "==", 111 ["="] = "==",
100 ["!="] = "~=" 112 ["!="] = "~=",
101 } 113 }
102 114
103 --- Consumes a constraint from a string, converting it to table format. 115
104 -- For example, a string ">= 1.0, > 2.0" is converted to a table in the 116
105 -- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned 117
106 -- back to the caller. 118
107 -- @param input string: A list of constraints in string format. 119
108 -- @return (table, string) or nil: A table representing the same 120
109 -- constraints and the string with the unused input, or nil if the 121
110 -- input string is invalid. 122
111 parse_constraint = function(input) 123 parse_constraint = function(input)
112 assert(type(input) == "string")
113 124
114 local no_upgrade, op, version, rest = input:match("^(@?)([<>=~!]*)%s*([%w%.%_%-]+)[%s,]*(.*)") 125 local no_upgrade, op, versionstr, rest = input:match("^(@?)([<>=~!]*)%s*([%w%.%_%-]+)[%s,]*(.*)")
115 local _op = operators[op] 126 local _op = operators[op]
116 version = vers.parse_version(version) 127 local version = vers.parse_version(versionstr)
117 if not _op then 128 if not _op then
118 return nil, "Encountered bad constraint operator: '"..tostring(op).."' in '"..input.."'" 129 return nil, "Encountered bad constraint operator: '" .. tostring(op) .. "' in '" .. input .. "'"
119 end 130 end
120 if not version then 131 if not version then
121 return nil, "Could not parse version from constraint: '"..input.."'" 132 return nil, "Could not parse version from constraint: '" .. input .. "'"
122 end 133 end
123 return { op = _op, version = version, no_upgrade = no_upgrade=="@" and true or nil }, rest 134 return { op = _op, version = version, no_upgrade = no_upgrade == "@" and true or nil }, rest
124 end 135 end
125 end 136 end
126 137
127 --- Convert a list of constraints from string to table format. 138
128 -- For example, a string ">= 1.0, < 2.0" is converted to a table in the format 139
129 -- {{op = ">=", version={1,0}}, {op = "<", version={2,0}}}. 140
130 -- Version tables use a metatable allowing later comparison through 141
131 -- relational operators. 142
132 -- @param input string: A list of constraints in string format. 143
133 -- @return table or nil: A table representing the same constraints, 144
134 -- or nil if the input string is invalid. 145
135 parse_constraints = function(input) 146 parse_constraints = function(input)
136 assert(type(input) == "string")
137 147
138 local constraints, oinput, constraint = {}, input 148 local constraints, oinput = {}, input
149 local constraint
139 while #input > 0 do 150 while #input > 0 do
140 constraint, input = parse_constraint(input) 151 constraint, input = parse_constraint(input)
141 if constraint then 152 if constraint then
142 table.insert(constraints, constraint) 153 table.insert(constraints, constraint)
143 else 154 else
144 return nil, "Failed to parse constraint '"..tostring(oinput).."' with error: ".. input 155 return nil, "Failed to parse constraint '" .. tostring(oinput) .. "' with error: " .. input
145 end 156 end
146 end 157 end
147 return constraints 158 return constraints
148 end 159 end
149 end 160 end
150 161
151 --- Prepare a query in dependency table format. 162
152 -- @param depstr string: A dependency in string format 163
153 -- as entered in rockspec files. 164
154 -- @return table: A query in table format, or nil and an error message in case of errors. 165
155 function queries.from_dep_string(depstr) 166 function queries.from_dep_string(depstr)
156 assert(type(depstr) == "string")
157 167
158 local ns_name, rest = depstr:match("^%s*([a-zA-Z0-9%.%-%_]*/?[a-zA-Z0-9][a-zA-Z0-9%.%-%_]*)%s*([^/]*)") 168 local ns_name, rest = depstr:match("^%s*([a-zA-Z0-9%.%-%_]*/?[a-zA-Z0-9][a-zA-Z0-9%.%-%_]*)%s*([^/]*)")
159 if not ns_name then 169 if not ns_name then
160 return nil, "failed to extract dependency name from '"..depstr.."'" 170 return nil, "failed to extract dependency name from '" .. depstr .. "'"
161 end 171 end
162 172
163 ns_name = ns_name:lower() 173 ns_name = ns_name:lower()
@@ -175,21 +185,22 @@ do
175 constraints = constraints, 185 constraints = constraints,
176 } 186 }
177 187
178 query_mt.arch[cfg.arch] = true 188 queries.Query.arch[cfg.arch] = true
179 return setmetatable(self, query_mt) 189 return setmetatable(self, query_mt)
180 end 190 end
181end 191end
182 192
183function queries.from_persisted_table(tbl) 193function queries.from_persisted_table(tbl)
184 query_mt.arch[cfg.arch] = true 194 queries.Query.arch[cfg.arch] = true
185 return setmetatable(tbl, query_mt) 195 return setmetatable(tbl, query_mt)
186end 196end
187 197
188--- Build a string representation of a query package name. 198
189-- Includes namespace, name and version, but not arch or constraints. 199
190-- @param query table: a query table 200
191-- @return string: a result such as `my_user/my_rock 1.0` or `my_rock`. 201
192function query_mt:__tostring() 202function query_mt.__tostring(self)
203
193 local out = {} 204 local out = {}
194 if self.namespace then 205 if self.namespace then
195 table.insert(out, self.namespace) 206 table.insert(out, self.namespace)
@@ -200,7 +211,14 @@ function query_mt:__tostring()
200 if #self.constraints > 0 then 211 if #self.constraints > 0 then
201 local pretty = {} 212 local pretty = {}
202 for _, c in ipairs(self.constraints) do 213 for _, c in ipairs(self.constraints) do
203 local v = c.version.string 214 local cv = c.version
215
216 local v
217 if type(cv) == "table" then
218 v = cv.string
219 else
220 v = cv
221 end
204 if c.op == "==" then 222 if c.op == "==" then
205 table.insert(pretty, v) 223 table.insert(pretty, v)
206 else 224 else
diff --git a/src/luarocks/queries.tl b/src/luarocks/queries.tl
index b5996dbe..15394c4d 100644
--- a/src/luarocks/queries.tl
+++ b/src/luarocks/queries.tl
@@ -1,15 +1,9 @@
1 1
2local record queries 2local record queries
3 record Constraint
4 version: vers.Version
5 op: string
6 no_upgrade: boolean
7 end
8
9 record Query 3 record Query
10 name: string 4 name: string
11 namespace: string 5 namespace: string
12 constraints: {Constraint} 6 constraints: {vers.Constraint}
13 substring: boolean 7 substring: boolean
14 arch: {string: boolean} 8 arch: {string: boolean}
15 end 9 end
@@ -22,18 +16,18 @@ local cfg = require("luarocks.core.cfg")
22-- local type Config = cfg 16-- local type Config = cfg
23 17
24local type Query = queries.Query 18local type Query = queries.Query
25local type Constraint = queries.Constraint 19local type Constraint = vers.Constraint
26 20
27local query_mt: metatable<Query> = {} 21local query_mt: metatable<Query> = {}
28 22
29query_mt.__index = query_mt 23query_mt.__index = queries.Query
30 24
31function query_mt.type() 25function queries.Query.type(): string --? remove later
32 return "query" 26 return "query"
33end 27end
34 28
35-- Fallback default value for the `arch` field, if not explicitly set. 29-- Fallback default value for the `arch` field, if not explicitly set.
36query_mt.arch = { 30queries.Query.arch = {
37 src = true, 31 src = true,
38 all = true, 32 all = true,
39 rockspec = true, 33 rockspec = true,
@@ -42,7 +36,7 @@ query_mt.arch = {
42} 36}
43 37
44-- Fallback default value for the `substring` field, if not explicitly set. 38-- Fallback default value for the `substring` field, if not explicitly set.
45query_mt.substring = false 39queries.Query.substring = false
46 40
47--- Convert the arch field of a query table to table format. 41--- Convert the arch field of a query table to table format.
48-- @param input string, table or nil 42-- @param input string, table or nil
@@ -87,7 +81,7 @@ function queries.new(name: string, namespace?: string, version?: string, substri
87 table.insert(self.constraints, { op = operator, version = vers.parse_version(version)}) 81 table.insert(self.constraints, { op = operator, version = vers.parse_version(version)})
88 end 82 end
89 83
90 query_mt.arch[cfg.arch] = true 84 queries.Query.arch[cfg.arch] = true
91 return setmetatable(self, query_mt) 85 return setmetatable(self, query_mt)
92end 86end
93 87
@@ -191,13 +185,13 @@ do
191 constraints = constraints, 185 constraints = constraints,
192 } 186 }
193 187
194 query_mt.arch[cfg.arch] = true 188 queries.Query.arch[cfg.arch] = true
195 return setmetatable(self, query_mt) 189 return setmetatable(self, query_mt)
196 end 190 end
197end 191end
198 192
199function queries.from_persisted_table(tbl: Query): Query 193function queries.from_persisted_table(tbl: Query): Query
200 query_mt.arch[cfg.arch] = true 194 queries.Query.arch[cfg.arch] = true
201 return setmetatable(tbl, query_mt) 195 return setmetatable(tbl, query_mt)
202end 196end
203 197
@@ -217,7 +211,14 @@ function query_mt.__tostring(self: Query): string
217 if #self.constraints > 0 then 211 if #self.constraints > 0 then
218 local pretty = {} 212 local pretty = {}
219 for _, c in ipairs(self.constraints) do 213 for _, c in ipairs(self.constraints) do
220 local v = c.version.string 214 local cv = c.version
215 -- local v = cv is vers.Version and cv.string or cv --TEAL BUG
216 local v: string
217 if cv is vers.Version then
218 v = cv.string
219 else
220 v = cv
221 end
221 if c.op == "==" then 222 if c.op == "==" then
222 table.insert(pretty, v) 223 table.insert(pretty, v)
223 else 224 else
@@ -231,4 +232,4 @@ function query_mt.__tostring(self: Query): string
231 return table.concat(out) 232 return table.concat(out)
232end 233end
233 234
234return queries --! src/luarocks/queries.tl:32 \ No newline at end of file 235return queries \ No newline at end of file