diff options
| author | Hisham Muhammad <hisham@gobolinux.org> | 2018-06-06 14:28:27 -0300 |
|---|---|---|
| committer | Hisham Muhammad <hisham@gobolinux.org> | 2018-06-14 14:06:51 -0300 |
| commit | c905deaa146dcd285b5b6a0edf0d569c52ea1e5a (patch) | |
| tree | e8dc97eb52ee4ebccaa9d4160c136c8c7e957fde | |
| parent | f8c877d486af39fc563b8a4107092682d49e4ae9 (diff) | |
| download | luarocks-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.lua | 42 | ||||
| -rw-r--r-- | spec/fixtures/autodetect/bla.lua | 1 | ||||
| -rw-r--r-- | src/luarocks/build.lua | 8 | ||||
| -rw-r--r-- | src/luarocks/build/builtin.lua | 86 | ||||
| -rw-r--r-- | src/luarocks/cmd/write_rockspec.lua | 56 |
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") | |||
| 10 | local cfg = require("luarocks.core.cfg") | 10 | local cfg = require("luarocks.core.cfg") |
| 11 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
| 12 | 12 | ||
| 13 | local 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 | ||
| 28 | end | ||
| 29 | |||
| 30 | do | ||
| 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 | ||
| 90 | end | ||
| 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 | ||
| 2 | local write_rockspec = {} | 2 | local write_rockspec = {} |
| 3 | 3 | ||
| 4 | local builtin = require("luarocks.build.builtin") | ||
| 4 | local cfg = require("luarocks.core.cfg") | 5 | local cfg = require("luarocks.core.cfg") |
| 5 | local dir = require("luarocks.dir") | 6 | local dir = require("luarocks.dir") |
| 6 | local fetch = require("luarocks.fetch") | 7 | local fetch = require("luarocks.fetch") |
| 7 | local fs = require("luarocks.fs") | 8 | local fs = require("luarocks.fs") |
| 8 | local path = require("luarocks.path") | ||
| 9 | local persist = require("luarocks.persist") | 9 | local persist = require("luarocks.persist") |
| 10 | local rockspecs = require("luarocks.rockspecs") | 10 | local rockspecs = require("luarocks.rockspecs") |
| 11 | local type_rockspec = require("luarocks.type.rockspec") | 11 | local type_rockspec = require("luarocks.type.rockspec") |
| @@ -172,31 +172,8 @@ local function check_license() | |||
| 172 | return nil, data | 172 | return nil, data |
| 173 | end | 173 | end |
| 174 | 174 | ||
| 175 | local 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_]+)")) | ||
| 181 | end | ||
| 182 | |||
| 183 | local luamod_blacklist = { | ||
| 184 | test = true, | ||
| 185 | tests = true, | ||
| 186 | } | ||
| 187 | |||
| 188 | local function fill_as_builtin(rockspec, libs) | 175 | local 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 | ||
| 241 | end | 189 | end |
| 242 | 190 | ||
| 243 | local function rockspec_cleanup(rockspec) | 191 | local function rockspec_cleanup(rockspec) |
