aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2018-06-06 14:28:27 -0300
committerHisham Muhammad <hisham@gobolinux.org>2018-06-14 14:06:51 -0300
commitc905deaa146dcd285b5b6a0edf0d569c52ea1e5a (patch)
treee8dc97eb52ee4ebccaa9d4160c136c8c7e957fde
parentf8c877d486af39fc563b8a4107092682d49e4ae9 (diff)
downloadluarocks-c905deaa146dcd285b5b6a0edf0d569c52ea1e5a.tar.gz
luarocks-c905deaa146dcd285b5b6a0edf0d569c52ea1e5a.tar.bz2
luarocks-c905deaa146dcd285b5b6a0edf0d569c52ea1e5a.zip
builtin: auto-detect modules when build.modules (or build!) is absent
-rw-r--r--spec/build_spec.lua42
-rw-r--r--spec/fixtures/autodetect/bla.lua1
-rw-r--r--src/luarocks/build.lua8
-rw-r--r--src/luarocks/build/builtin.lua86
-rw-r--r--src/luarocks/cmd/write_rockspec.lua56
5 files changed, 137 insertions, 56 deletions
diff --git a/spec/build_spec.lua b/spec/build_spec.lua
index b703478e..af2dfe38 100644
--- a/spec/build_spec.lua
+++ b/spec/build_spec.lua
@@ -269,6 +269,48 @@ describe("LuaRocks build tests #integration", function()
269 assert.truthy(run.luarocks_bool("build " .. rockspec)) 269 assert.truthy(run.luarocks_bool("build " .. rockspec))
270 assert.is.truthy(run.luarocks("show a_rock")) 270 assert.is.truthy(run.luarocks("show a_rock"))
271 end) 271 end)
272
273 it("'builtin' detects lua files if modules are not given", function()
274 local rockspec = "autodetect-1.0-1.rockspec"
275 test_env.write_file(rockspec, [[
276 rockspec_format = "3.0"
277 package = "autodetect"
278 version = "1.0-1"
279 source = {
280 url = "file://]] .. testing_paths.fixtures_dir .. [[/autodetect/bla.lua"
281 }
282 description = {
283 summary = "An example rockspec",
284 }
285 dependencies = {
286 "lua >= 5.1"
287 }
288 build = {
289 }
290 ]], finally)
291 assert.truthy(run.luarocks_bool("build " .. rockspec))
292 assert.match("bla.lua", run.luarocks("show autodetect"))
293 end)
294
295 it("'builtin' detects lua files if build is not given", function()
296 local rockspec = "autodetect-1.0-1.rockspec"
297 test_env.write_file(rockspec, [[
298 rockspec_format = "3.0"
299 package = "autodetect"
300 version = "1.0-1"
301 source = {
302 url = "file://]] .. testing_paths.fixtures_dir .. [[/autodetect/bla.lua"
303 }
304 description = {
305 summary = "An example rockspec",
306 }
307 dependencies = {
308 "lua >= 5.1"
309 }
310 ]], finally)
311 assert.truthy(run.luarocks_bool("build " .. rockspec))
312 assert.match("bla.lua", run.luarocks("show autodetect"))
313 end)
272 end) 314 end)
273 315
274 describe("#mock external dependencies", function() 316 describe("#mock external dependencies", function()
diff --git a/spec/fixtures/autodetect/bla.lua b/spec/fixtures/autodetect/bla.lua
new file mode 100644
index 00000000..a5647075
--- /dev/null
+++ b/spec/fixtures/autodetect/bla.lua
@@ -0,0 +1 @@
return {}
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua
index ac4ecfad..0cfbccd7 100644
--- a/src/luarocks/build.lua
+++ b/src/luarocks/build.lua
@@ -353,7 +353,13 @@ function build.build_rockspec(rockspec, opts)
353 assert(opts:type() == "build.opts") 353 assert(opts:type() == "build.opts")
354 354
355 if not rockspec.build then 355 if not rockspec.build then
356 return nil, "Rockspec error: build table not specified" 356 if rockspec:format_is_at_least("3.0") then
357 rockspec.build = {
358 type = "builtin"
359 }
360 else
361 return nil, "Rockspec error: build table not specified"
362 end
357 end 363 end
358 364
359 if not rockspec.build.type then 365 if not rockspec.build.type then
diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua
index 41cc31b0..4ff59f8b 100644
--- a/src/luarocks/build/builtin.lua
+++ b/src/luarocks/build/builtin.lua
@@ -10,6 +10,85 @@ local util = require("luarocks.util")
10local cfg = require("luarocks.core.cfg") 10local cfg = require("luarocks.core.cfg")
11local dir = require("luarocks.dir") 11local dir = require("luarocks.dir")
12 12
13local function autoextract_libs(external_dependencies, variables)
14 if not external_dependencies then
15 return nil, nil, nil
16 end
17 local libs = {}
18 local incdirs = {}
19 local libdirs = {}
20 for name, data in pairs(external_dependencies) do
21 if data.library then
22 table.insert(libs, data.library)
23 table.insert(incdirs, variables[name .. "_INCDIR"])
24 table.insert(libdirs, variables[name .. "_LIBDIR"])
25 end
26 end
27 return libs, incdirs, libdirs
28end
29
30do
31 local function get_cmod_name(file)
32 local fd = io.open(dir.path(fs.current_dir(), file), "r")
33 if not fd then return nil end
34 local data = fd:read("*a")
35 fd:close()
36 return (data:match("int%s+luaopen_([a-zA-Z0-9_]+)"))
37 end
38
39 local luamod_blacklist = {
40 test = true,
41 tests = true,
42 }
43
44 function builtin.autodetect_modules(libs, incdirs, libdirs)
45 local modules = {}
46 local copy_directories
47
48 local prefix = ""
49 for _, parent in ipairs({"src", "lua"}) do
50 if fs.is_dir(parent) then
51 fs.change_dir(parent)
52 prefix = parent.."/"
53 break
54 end
55 end
56
57 for _, file in ipairs(fs.find()) do
58 local luamod = file:match("(.*)%.lua$")
59 if luamod and not luamod_blacklist[luamod] then
60 modules[path.path_to_module(file)] = prefix..file
61 else
62 local cmod = file:match("(.*)%.c$")
63 if cmod then
64 local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua"))
65 modules[modname] = {
66 sources = prefix..file,
67 libraries = libs,
68 incdirs = incdirs,
69 libdirs = libdirs,
70 }
71 end
72 end
73 end
74
75 for _, directory in ipairs({ "doc", "docs", "samples", "tests" }) do
76 if fs.is_dir(directory) then
77 if not copy_directories then
78 copy_directories = {}
79 end
80 table.insert(copy_directories, directory)
81 end
82 end
83
84 if prefix ~= "" then
85 fs.pop_dir()
86 end
87
88 return modules, copy_directories
89 end
90end
91
13--- Run a command displaying its execution on standard output. 92--- Run a command displaying its execution on standard output.
14-- @return boolean: true if command succeeds (status code 0), false 93-- @return boolean: true if command succeeds (status code 0), false
15-- otherwise. 94-- otherwise.
@@ -140,7 +219,12 @@ function builtin.run(rockspec)
140 local libdir = path.lib_dir(rockspec.name, rockspec.version) 219 local libdir = path.lib_dir(rockspec.name, rockspec.version)
141 220
142 if not build.modules then 221 if not build.modules then
143 return nil, "Missing build.modules table" 222 if rockspec:format_is_at_least("3.0") then
223 local libs, incdirs, libdirs = autoextract_libs(rockspec.external_dependencies, rockspec.variables)
224 build.modules = builtin.autodetect_modules(libs, incdirs, libdirs)
225 else
226 return nil, "Missing build.modules table"
227 end
144 end 228 end
145 for name, info in pairs(build.modules) do 229 for name, info in pairs(build.modules) do
146 local moddir = path.module_to_path(name) 230 local moddir = path.module_to_path(name)
diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua
index 36beffd0..b4007e85 100644
--- a/src/luarocks/cmd/write_rockspec.lua
+++ b/src/luarocks/cmd/write_rockspec.lua
@@ -1,11 +1,11 @@
1 1
2local write_rockspec = {} 2local write_rockspec = {}
3 3
4local builtin = require("luarocks.build.builtin")
4local cfg = require("luarocks.core.cfg") 5local cfg = require("luarocks.core.cfg")
5local dir = require("luarocks.dir") 6local dir = require("luarocks.dir")
6local fetch = require("luarocks.fetch") 7local fetch = require("luarocks.fetch")
7local fs = require("luarocks.fs") 8local fs = require("luarocks.fs")
8local path = require("luarocks.path")
9local persist = require("luarocks.persist") 9local persist = require("luarocks.persist")
10local rockspecs = require("luarocks.rockspecs") 10local rockspecs = require("luarocks.rockspecs")
11local type_rockspec = require("luarocks.type.rockspec") 11local type_rockspec = require("luarocks.type.rockspec")
@@ -172,31 +172,8 @@ local function check_license()
172 return nil, data 172 return nil, data
173end 173end
174 174
175local function get_cmod_name(file)
176 local fd = open_file(file)
177 if not fd then return nil end
178 local data = fd:read("*a")
179 fd:close()
180 return (data:match("int%s+luaopen_([a-zA-Z0-9_]+)"))
181end
182
183local luamod_blacklist = {
184 test = true,
185 tests = true,
186}
187
188local function fill_as_builtin(rockspec, libs) 175local function fill_as_builtin(rockspec, libs)
189 rockspec.build.type = "builtin" 176 rockspec.build.type = "builtin"
190 rockspec.build.modules = {}
191 local prefix = ""
192
193 for _, parent in ipairs({"src", "lua"}) do
194 if fs.is_dir(parent) then
195 fs.change_dir(parent)
196 prefix = parent.."/"
197 break
198 end
199 end
200 177
201 local incdirs, libdirs 178 local incdirs, libdirs
202 if libs then 179 if libs then
@@ -207,37 +184,8 @@ local function fill_as_builtin(rockspec, libs)
207 libdirs[#libdirs+1] = "$("..upper.."_LIBDIR)" 184 libdirs[#libdirs+1] = "$("..upper.."_LIBDIR)"
208 end 185 end
209 end 186 end
210
211 for _, file in ipairs(fs.find()) do
212 local luamod = file:match("(.*)%.lua$")
213 if luamod and not luamod_blacklist[luamod] then
214 rockspec.build.modules[path.path_to_module(file)] = prefix..file
215 else
216 local cmod = file:match("(.*)%.c$")
217 if cmod then
218 local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua"))
219 rockspec.build.modules[modname] = {
220 sources = prefix..file,
221 libraries = libs,
222 incdirs = incdirs,
223 libdirs = libdirs,
224 }
225 end
226 end
227 end
228 187
229 for _, directory in ipairs({ "doc", "docs", "samples", "tests" }) do 188 rockspec.build.modules, rockspec.build.copy_directories = builtin.autodetect_modules(libs, incdirs, libdirs)
230 if fs.is_dir(directory) then
231 if not rockspec.build.copy_directories then
232 rockspec.build.copy_directories = {}
233 end
234 table.insert(rockspec.build.copy_directories, directory)
235 end
236 end
237
238 if prefix ~= "" then
239 fs.pop_dir()
240 end
241end 189end
242 190
243local function rockspec_cleanup(rockspec) 191local function rockspec_cleanup(rockspec)