diff options
-rw-r--r-- | src/luarocks/cmd/write_rockspec.tl (renamed from src/luarocks/cmd/write_rockspec.lua) | 127 |
1 files changed, 71 insertions, 56 deletions
diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.tl index 871cdd44..6ece30da 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.tl | |||
@@ -1,5 +1,6 @@ | |||
1 | 1 | ||
2 | local write_rockspec = {} | 2 | local record write_rockspec |
3 | end | ||
3 | 4 | ||
4 | local builtin = require("luarocks.build.builtin") | 5 | local builtin = require("luarocks.build.builtin") |
5 | local cfg = require("luarocks.core.cfg") | 6 | local cfg = require("luarocks.core.cfg") |
@@ -11,6 +12,17 @@ local rockspecs = require("luarocks.rockspecs") | |||
11 | local type_rockspec = require("luarocks.type.rockspec") | 12 | local type_rockspec = require("luarocks.type.rockspec") |
12 | local util = require("luarocks.util") | 13 | local util = require("luarocks.util") |
13 | 14 | ||
15 | local type Parser = require("luarocks.vendor.argparse").Parser | ||
16 | |||
17 | local type Args = require("luarocks.core.types.args").Args | ||
18 | |||
19 | local type PersistableTable = require("luarocks.core.types.persist").PersistableTable | ||
20 | |||
21 | local type BuiltinBuild = require("luarocks.core.types.build").BuiltinBuild | ||
22 | |||
23 | local type Rockspec = require("luarocks.core.types.rockspec").Rockspec | ||
24 | local type Dependencies = require("luarocks.core.types.rockspec").Dependencies | ||
25 | |||
14 | local lua_versions = { | 26 | local lua_versions = { |
15 | "5.1", | 27 | "5.1", |
16 | "5.2", | 28 | "5.2", |
@@ -24,31 +36,31 @@ local lua_versions = { | |||
24 | "5.1,5.2,5.3,5.4" | 36 | "5.1,5.2,5.3,5.4" |
25 | } | 37 | } |
26 | 38 | ||
27 | function write_rockspec.cmd_options(parser) | 39 | function write_rockspec.cmd_options(parser: Parser) |
28 | return parser:option("--output", "Write the rockspec with the given filename.\n".. | 40 | parser:option("--output", "Write the rockspec with the given filename.\n".. |
29 | "If not given, a file is written in the current directory with a ".. | 41 | "If not given, a file is written in the current directory with a ".. |
30 | "filename based on given name and version.") | 42 | "filename based on given name and version.") |
31 | :argname("<file>"), | 43 | :argname("<file>") |
32 | parser:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') | 44 | parser:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') |
33 | :argname("<string>"), | 45 | :argname("<string>") |
34 | parser:option("--summary", "A short one-line description summary.") | 46 | parser:option("--summary", "A short one-line description summary.") |
35 | :argname("<txt>"), | 47 | :argname("<txt>") |
36 | parser:option("--detailed", "A longer description string.") | 48 | parser:option("--detailed", "A longer description string.") |
37 | :argname("<txt>"), | 49 | :argname("<txt>") |
38 | parser:option("--homepage", "Project homepage.") | 50 | parser:option("--homepage", "Project homepage.") |
39 | :argname("<txt>"), | 51 | :argname("<txt>") |
40 | parser:option("--lua-versions", 'Supported Lua versions. Accepted values are: "'.. | 52 | parser:option("--lua-versions", 'Supported Lua versions. Accepted values are: "'.. |
41 | table.concat(lua_versions, '", "')..'".') | 53 | table.concat(lua_versions, '", "')..'".') |
42 | :argname("<ver>") | 54 | :argname("<ver>") |
43 | :choices(lua_versions), | 55 | :choices(lua_versions) |
44 | parser:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') | 56 | parser:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') |
45 | :argname("<ver>"), | 57 | :argname("<ver>") |
46 | parser:option("--tag", "Tag to use. Will attempt to extract version number from it."), | 58 | parser:option("--tag", "Tag to use. Will attempt to extract version number from it.") |
47 | parser:option("--lib", "A comma-separated list of libraries that C files need to link to.") | 59 | parser:option("--lib", "A comma-separated list of libraries that C files need to link to.") |
48 | :argname("<libs>") | 60 | :argname("<libs>") |
49 | end | 61 | end |
50 | 62 | ||
51 | function write_rockspec.add_to_parser(parser) | 63 | function write_rockspec.add_to_parser(parser: Parser) |
52 | local cmd = parser:command("write_rockspec", [[ | 64 | local cmd = parser:command("write_rockspec", [[ |
53 | This command writes an initial version of a rockspec file, | 65 | This command writes an initial version of a rockspec file, |
54 | based on a name, a version, and a location (an URL or a local path). | 66 | based on a name, a version, and a location (an URL or a local path). |
@@ -70,14 +82,14 @@ rockspec, and is not guaranteed to be complete or correct. ]], util.see_also()) | |||
70 | cmd:argument("location", "URL or path to the rock sources.") | 82 | cmd:argument("location", "URL or path to the rock sources.") |
71 | :args("?") | 83 | :args("?") |
72 | 84 | ||
73 | write_rockspec.cmd_options(cmd) | 85 | write_rockspec.cmd_options(cmd as Parser) |
74 | end | 86 | end |
75 | 87 | ||
76 | local function open_file(name) | 88 | local function open_file(name: string): FILE, string, integer |
77 | return io.open(dir.path(fs.current_dir(), name), "r") | 89 | return io.open(dir.path(fs.current_dir(), name), "r") |
78 | end | 90 | end |
79 | 91 | ||
80 | local function fetch_url(rockspec) | 92 | local function fetch_url(rockspec: Rockspec): boolean, string, string |
81 | local file, temp_dir, err_code, err_file, err_temp_dir = fetch.fetch_sources(rockspec, false) | 93 | local file, temp_dir, err_code, err_file, err_temp_dir = fetch.fetch_sources(rockspec, false) |
82 | if err_code == "source.dir" then | 94 | if err_code == "source.dir" then |
83 | file, temp_dir = err_file, err_temp_dir | 95 | file, temp_dir = err_file, err_temp_dir |
@@ -117,9 +129,9 @@ local simple_scm_protocols = { | |||
117 | ["hg+ssh"] = true, | 129 | ["hg+ssh"] = true, |
118 | } | 130 | } |
119 | 131 | ||
120 | local detect_url | 132 | local detect_url: function(string): string |
121 | do | 133 | do |
122 | local function detect_url_from_command(program, args, directory) | 134 | local function detect_url_from_command(program: string, args: string, directory: string): string |
123 | local command = fs.Q(cfg.variables[program:upper()]).. " "..args | 135 | local command = fs.Q(cfg.variables[program:upper()]).. " "..args |
124 | local pipe = io.popen(fs.command_at(directory, fs.quiet_stderr(command))) | 136 | local pipe = io.popen(fs.command_at(directory, fs.quiet_stderr(command))) |
125 | if not pipe then return nil end | 137 | if not pipe then return nil end |
@@ -133,17 +145,17 @@ do | |||
133 | url = program.."+"..url | 145 | url = program.."+"..url |
134 | end | 146 | end |
135 | 147 | ||
136 | if simple_scm_protocols[dir.split_url(url)] then | 148 | if (simple_scm_protocols as {string: boolean})[dir.split_url(url)] then |
137 | return url | 149 | return url |
138 | end | 150 | end |
139 | end | 151 | end |
140 | 152 | ||
141 | local function detect_scm_url(directory) | 153 | local function detect_scm_url(directory: string): string |
142 | return detect_url_from_command("git", "config --get remote.origin.url", directory) or | 154 | return detect_url_from_command("git", "config --get remote.origin.url", directory) or |
143 | detect_url_from_command("hg", "paths default", directory) | 155 | detect_url_from_command("hg", "paths default", directory) |
144 | end | 156 | end |
145 | 157 | ||
146 | detect_url = function(url_or_dir) | 158 | detect_url = function(url_or_dir: string): string |
147 | if url_or_dir:match("://") then | 159 | if url_or_dir:match("://") then |
148 | return url_or_dir | 160 | return url_or_dir |
149 | else | 161 | else |
@@ -152,13 +164,13 @@ do | |||
152 | end | 164 | end |
153 | end | 165 | end |
154 | 166 | ||
155 | local function detect_homepage(url, homepage) | 167 | local function detect_homepage(url: string, homepage: string): string |
156 | if homepage then | 168 | if homepage then |
157 | return homepage | 169 | return homepage |
158 | end | 170 | end |
159 | local url_protocol, url_path = dir.split_url(url) | 171 | local url_protocol, url_path = dir.split_url(url) |
160 | 172 | ||
161 | if simple_scm_protocols[url_protocol] then | 173 | if (simple_scm_protocols as {string: boolean})[url_protocol] then |
162 | for _, domain in ipairs({"github.com", "bitbucket.org", "gitlab.com"}) do | 174 | for _, domain in ipairs({"github.com", "bitbucket.org", "gitlab.com"}) do |
163 | if util.starts_with(url_path, domain) then | 175 | if util.starts_with(url_path, domain) then |
164 | return "https://"..url_path:gsub("%.git$", "") | 176 | return "https://"..url_path:gsub("%.git$", "") |
@@ -169,14 +181,14 @@ local function detect_homepage(url, homepage) | |||
169 | return "*** please enter a project homepage ***" | 181 | return "*** please enter a project homepage ***" |
170 | end | 182 | end |
171 | 183 | ||
172 | local function detect_description() | 184 | local function detect_description(): string, string |
173 | local fd = open_file("README.md") or open_file("README") | 185 | local fd = open_file("README.md") or open_file("README") |
174 | if not fd then return end | 186 | if not fd then return end |
175 | local data = fd:read("*a") | 187 | local data = fd:read("*a") |
176 | fd:close() | 188 | fd:close() |
177 | local paragraph = data:match("\n\n([^%[].-)\n\n") | 189 | local paragraph = data:match("\n\n([^%[].-)\n\n") |
178 | if not paragraph then paragraph = data:match("\n\n(.*)") end | 190 | if not paragraph then paragraph = data:match("\n\n(.*)") end |
179 | local summary, detailed | 191 | local summary, detailed: string, string |
180 | if paragraph then | 192 | if paragraph then |
181 | detailed = paragraph | 193 | detailed = paragraph |
182 | 194 | ||
@@ -194,7 +206,7 @@ local licenses = { | |||
194 | [49311] = "ISC", | 206 | [49311] = "ISC", |
195 | } | 207 | } |
196 | 208 | ||
197 | local function detect_license(data) | 209 | local function detect_license(data: string): string |
198 | local strip_copyright = (data:gsub("^Copyright [^\n]*\n", "")) | 210 | local strip_copyright = (data:gsub("^Copyright [^\n]*\n", "")) |
199 | local sum = 0 | 211 | local sum = 0 |
200 | for i = 1, #strip_copyright do | 212 | for i = 1, #strip_copyright do |
@@ -206,7 +218,7 @@ local function detect_license(data) | |||
206 | return licenses[sum] | 218 | return licenses[sum] |
207 | end | 219 | end |
208 | 220 | ||
209 | local function check_license() | 221 | local function check_license(): string, string |
210 | local fd = open_file("COPYING") or open_file("LICENSE") or open_file("MIT-LICENSE.txt") | 222 | local fd = open_file("COPYING") or open_file("LICENSE") or open_file("MIT-LICENSE.txt") |
211 | if not fd then return nil end | 223 | if not fd then return nil end |
212 | local data = fd:read("*a") | 224 | local data = fd:read("*a") |
@@ -218,10 +230,10 @@ local function check_license() | |||
218 | return nil, data | 230 | return nil, data |
219 | end | 231 | end |
220 | 232 | ||
221 | local function fill_as_builtin(rockspec, libs) | 233 | local function fill_as_builtin(rockspec: Rockspec, libs: {string}) |
222 | rockspec.build.type = "builtin" | 234 | rockspec.build.type = "builtin" |
223 | 235 | ||
224 | local incdirs, libdirs | 236 | local incdirs, libdirs: {string}, {string} |
225 | if libs then | 237 | if libs then |
226 | incdirs, libdirs = {}, {} | 238 | incdirs, libdirs = {}, {} |
227 | for _, lib in ipairs(libs) do | 239 | for _, lib in ipairs(libs) do |
@@ -230,11 +242,10 @@ local function fill_as_builtin(rockspec, libs) | |||
230 | libdirs[#libdirs+1] = "$("..upper.."_LIBDIR)" | 242 | libdirs[#libdirs+1] = "$("..upper.."_LIBDIR)" |
231 | end | 243 | end |
232 | end | 244 | end |
233 | 245 | (rockspec.build as BuiltinBuild).modules, rockspec.build.install, rockspec.build.copy_directories = builtin.autodetect_modules(libs, incdirs, libdirs) | |
234 | rockspec.build.modules, rockspec.build.install, rockspec.build.copy_directories = builtin.autodetect_modules(libs, incdirs, libdirs) | ||
235 | end | 246 | end |
236 | 247 | ||
237 | local function rockspec_cleanup(rockspec) | 248 | local function rockspec_cleanup(rockspec: Rockspec) |
238 | rockspec.source.file = nil | 249 | rockspec.source.file = nil |
239 | rockspec.source.protocol = nil | 250 | rockspec.source.protocol = nil |
240 | rockspec.source.identifier = nil | 251 | rockspec.source.identifier = nil |
@@ -246,21 +257,25 @@ local function rockspec_cleanup(rockspec) | |||
246 | rockspec.format_is_at_least = nil | 257 | rockspec.format_is_at_least = nil |
247 | rockspec.local_abs_filename = nil | 258 | rockspec.local_abs_filename = nil |
248 | rockspec.rocks_provided = nil | 259 | rockspec.rocks_provided = nil |
249 | for _, list in ipairs({"dependencies", "build_dependencies", "test_dependencies"}) do | 260 | |
250 | if rockspec[list] and not next(rockspec[list]) then | 261 | local dep_lists: {string: Dependencies} = { |
251 | rockspec[list] = nil | 262 | dependencies = rockspec.dependencies, |
252 | end | 263 | build_dependencies = rockspec.build_dependencies, |
253 | end | 264 | test_dependencies = rockspec.test_dependencies, |
254 | for _, list in ipairs({"dependencies", "build_dependencies", "test_dependencies"}) do | 265 | } |
255 | if rockspec[list] then | 266 | |
256 | for i, entry in ipairs(rockspec[list]) do | 267 | for name, data in pairs(dep_lists) do |
257 | rockspec[list][i] = tostring(entry) | 268 | if not next(data) then |
269 | (rockspec as {string: Dependencies})[name] = nil | ||
270 | else | ||
271 | for i, item in ipairs(data) do | ||
272 | data[i] = tostring(item) | ||
258 | end | 273 | end |
259 | end | 274 | end |
260 | end | 275 | end |
261 | end | 276 | end |
262 | 277 | ||
263 | function write_rockspec.command(args) | 278 | function write_rockspec.command(args: Args): boolean, string |
264 | local name, version = args.name, args.version | 279 | local name, version = args.name, args.version |
265 | local location = args.location | 280 | local location = args.location |
266 | 281 | ||
@@ -321,7 +336,7 @@ function write_rockspec.command(args) | |||
321 | license = args.license or "*** please specify a license ***", | 336 | license = args.license or "*** please specify a license ***", |
322 | }, | 337 | }, |
323 | dependencies = { | 338 | dependencies = { |
324 | lua_version_dep[args.lua_versions], | 339 | (lua_version_dep as {string: string})[args.lua_versions], |
325 | }, | 340 | }, |
326 | build = {}, | 341 | build = {}, |
327 | }) | 342 | }) |
@@ -359,7 +374,7 @@ function write_rockspec.command(args) | |||
359 | local_dir = "." | 374 | local_dir = "." |
360 | end | 375 | end |
361 | 376 | ||
362 | local libs = nil | 377 | local libs: {string} = nil |
363 | if args.lib then | 378 | if args.lib then |
364 | libs = {} | 379 | libs = {} |
365 | rockspec.external_dependencies = {} | 380 | rockspec.external_dependencies = {} |
@@ -396,7 +411,7 @@ function write_rockspec.command(args) | |||
396 | 411 | ||
397 | rockspec_cleanup(rockspec) | 412 | rockspec_cleanup(rockspec) |
398 | 413 | ||
399 | persist.save_from_table(filename, rockspec, type_rockspec.order) | 414 | persist.save_from_table(filename, rockspec as PersistableTable, type_rockspec.order) |
400 | 415 | ||
401 | util.printout() | 416 | util.printout() |
402 | util.printout("Wrote template at "..filename.." -- you should now edit and finish it.") | 417 | util.printout("Wrote template at "..filename.." -- you should now edit and finish it.") |