aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
2local write_rockspec = {} 2local record write_rockspec
3end
3 4
4local builtin = require("luarocks.build.builtin") 5local builtin = require("luarocks.build.builtin")
5local cfg = require("luarocks.core.cfg") 6local cfg = require("luarocks.core.cfg")
@@ -11,6 +12,17 @@ local rockspecs = require("luarocks.rockspecs")
11local type_rockspec = require("luarocks.type.rockspec") 12local type_rockspec = require("luarocks.type.rockspec")
12local util = require("luarocks.util") 13local util = require("luarocks.util")
13 14
15local type Parser = require("luarocks.vendor.argparse").Parser
16
17local type Args = require("luarocks.core.types.args").Args
18
19local type PersistableTable = require("luarocks.core.types.persist").PersistableTable
20
21local type BuiltinBuild = require("luarocks.core.types.build").BuiltinBuild
22
23local type Rockspec = require("luarocks.core.types.rockspec").Rockspec
24local type Dependencies = require("luarocks.core.types.rockspec").Dependencies
25
14local lua_versions = { 26local 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
27function write_rockspec.cmd_options(parser) 39function 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>")
49end 61end
50 62
51function write_rockspec.add_to_parser(parser) 63function write_rockspec.add_to_parser(parser: Parser)
52 local cmd = parser:command("write_rockspec", [[ 64 local cmd = parser:command("write_rockspec", [[
53This command writes an initial version of a rockspec file, 65This command writes an initial version of a rockspec file,
54based on a name, a version, and a location (an URL or a local path). 66based 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)
74end 86end
75 87
76local function open_file(name) 88local 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")
78end 90end
79 91
80local function fetch_url(rockspec) 92local 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
120local detect_url 132local detect_url: function(string): string
121do 133do
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
153end 165end
154 166
155local function detect_homepage(url, homepage) 167local 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 ***"
170end 182end
171 183
172local function detect_description() 184local 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
197local function detect_license(data) 209local 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]
207end 219end
208 220
209local function check_license() 221local 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
219end 231end
220 232
221local function fill_as_builtin(rockspec, libs) 233local 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)
235end 246end
236 247
237local function rockspec_cleanup(rockspec) 248local 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
261end 276end
262 277
263function write_rockspec.command(args) 278function 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.")