diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2019-03-21 18:47:44 -0400 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2019-04-01 16:26:30 -0300 |
commit | e388deecaa13b7b89da202d09d328a79bbcf40dd (patch) | |
tree | 1adcd8df720b0bb247f141342efed1f851341b52 | |
parent | 5cdaa0ad83f79e7c8ecfa87e5d58f4a42d907a44 (diff) | |
download | luarocks-e388deecaa13b7b89da202d09d328a79bbcf40dd.tar.gz luarocks-e388deecaa13b7b89da202d09d328a79bbcf40dd.tar.bz2 luarocks-e388deecaa13b7b89da202d09d328a79bbcf40dd.zip |
cmd: refactor detection code and improve detection of project dir
-rw-r--r-- | spec/init_spec.lua | 4 | ||||
-rw-r--r-- | src/luarocks/cmd.lua | 198 | ||||
-rw-r--r-- | src/luarocks/core/cfg.lua | 50 | ||||
-rw-r--r-- | src/luarocks/util.lua | 109 |
4 files changed, 189 insertions, 172 deletions
diff --git a/spec/init_spec.lua b/spec/init_spec.lua index 2c8dd64c..22570df2 100644 --- a/spec/init_spec.lua +++ b/spec/init_spec.lua | |||
@@ -111,7 +111,9 @@ describe("Luarocks init test #integration", function() | |||
111 | ]], finally) | 111 | ]], finally) |
112 | write_file(tmpdir .. "/my_dependency.lua", "return {}", finally) | 112 | write_file(tmpdir .. "/my_dependency.lua", "return {}", finally) |
113 | 113 | ||
114 | assert.is_true(run.luarocks_bool("build --verbose my_dependency-1.0-1.rockspec")) | 114 | print(run.luarocks("install inspect")) |
115 | |||
116 | print(run.luarocks("build --verbose my_dependency-1.0-1.rockspec")) | ||
115 | assert.truthy(lfs.attributes(myproject .. "/lua_modules/share/lua/" .. test_env.lua_version .."/my_dependency.lua")) | 117 | assert.truthy(lfs.attributes(myproject .. "/lua_modules/share/lua/" .. test_env.lua_version .."/my_dependency.lua")) |
116 | 118 | ||
117 | os.remove(rockspec_filename) | 119 | os.remove(rockspec_filename) |
diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 4397d43b..a46b0722 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua | |||
@@ -38,106 +38,6 @@ local function is_ownership_ok(directory) | |||
38 | return false | 38 | return false |
39 | end | 39 | end |
40 | 40 | ||
41 | local function exists(file) | ||
42 | local fd = io.open(file, "r") | ||
43 | if fd then | ||
44 | fd:close() | ||
45 | return true | ||
46 | end | ||
47 | return false | ||
48 | end | ||
49 | |||
50 | do | ||
51 | local function Q(pathname) | ||
52 | if pathname:match("^.:") then | ||
53 | return pathname:sub(1, 2) .. '"' .. pathname:sub(3) .. '"' | ||
54 | end | ||
55 | return '"' .. pathname .. '"' | ||
56 | end | ||
57 | |||
58 | local function check_lua_version(lua_exe, luaver) | ||
59 | if not exists(lua_exe) then | ||
60 | return nil | ||
61 | end | ||
62 | local lv, err = util.popen_read(Q(lua_exe) .. ' -e "io.write(_VERSION:sub(5))"') | ||
63 | if luaver and luaver ~= lv then | ||
64 | return nil | ||
65 | end | ||
66 | local ljv | ||
67 | if lv == "5.1" then | ||
68 | ljv = util.popen_read(Q(lua_exe) .. ' -e "io.write(tostring(jit and jit.version:sub(8)))"') | ||
69 | if ljv == "nil" then | ||
70 | ljv = nil | ||
71 | end | ||
72 | end | ||
73 | return lv, ljv | ||
74 | end | ||
75 | |||
76 | local find_lua_bindir | ||
77 | do | ||
78 | local exe_suffix = (package.config:sub(1, 1) == "\\" and ".exe" or "") | ||
79 | |||
80 | local function insert_lua_versions(names, luaver) | ||
81 | local variants = { | ||
82 | "lua" .. luaver .. exe_suffix, | ||
83 | "lua" .. luaver:gsub("%.", "") .. exe_suffix, | ||
84 | "lua-" .. luaver .. exe_suffix, | ||
85 | "lua-" .. luaver:gsub("%.", "") .. exe_suffix, | ||
86 | } | ||
87 | for _, name in ipairs(variants) do | ||
88 | names[name] = luaver | ||
89 | table.insert(names, name) | ||
90 | end | ||
91 | end | ||
92 | |||
93 | find_lua_bindir = function(prefix, luaver) | ||
94 | local names = {} | ||
95 | if luaver then | ||
96 | insert_lua_versions(names, luaver) | ||
97 | else | ||
98 | for v in util.lua_versions("descending") do | ||
99 | insert_lua_versions(names, v) | ||
100 | end | ||
101 | end | ||
102 | if luaver == "5.1" or not luaver then | ||
103 | table.insert(names, "luajit" .. exe_suffix) | ||
104 | end | ||
105 | table.insert(names, "lua" .. exe_suffix) | ||
106 | |||
107 | local bindirs = { prefix .. "/bin", prefix } | ||
108 | local tried = {} | ||
109 | for _, d in ipairs(bindirs) do | ||
110 | for _, name in ipairs(names) do | ||
111 | local lua_exe = dir.path(d, name) | ||
112 | table.insert(tried, lua_exe) | ||
113 | local lv, ljv = check_lua_version(lua_exe, luaver) | ||
114 | if lv then | ||
115 | return name, d, lv, ljv | ||
116 | end | ||
117 | end | ||
118 | end | ||
119 | return nil, "Lua interpreter not found at " .. prefix .. "\n" .. | ||
120 | "Tried:\t" .. table.concat(tried, "\n\t") | ||
121 | end | ||
122 | end | ||
123 | |||
124 | function cmd.find_lua(prefix, luaver) | ||
125 | local lua_interpreter, bindir, luajitver | ||
126 | lua_interpreter, bindir, luaver, luajitver = find_lua_bindir(prefix, luaver) | ||
127 | if not lua_interpreter then | ||
128 | return nil, bindir | ||
129 | end | ||
130 | |||
131 | return { | ||
132 | lua_version = luaver, | ||
133 | luajit_version = luajitver, | ||
134 | lua_interpreter = lua_interpreter, | ||
135 | lua_dir = prefix, | ||
136 | lua_bindir = bindir, | ||
137 | } | ||
138 | end | ||
139 | end | ||
140 | |||
141 | local function check_popen() | 41 | local function check_popen() |
142 | local popen_ok, popen_result = pcall(io.popen, "") | 42 | local popen_ok, popen_result = pcall(io.popen, "") |
143 | if popen_ok then | 43 | if popen_ok then |
@@ -151,16 +51,17 @@ local function check_popen() | |||
151 | end | 51 | end |
152 | end | 52 | end |
153 | 53 | ||
154 | local function find_project_dir() | 54 | local function check_if_config_is_present(detected, try) |
155 | local try = "." | 55 | local versions = detected.lua_version |
156 | for _ = 1, 10 do -- FIXME detect when root dir was hit instead | 56 | and { detected.lua_version } |
157 | if exists(try .. "/.luarocks") and exists(try .. "/lua_modules") then | 57 | or util.lua_versions("descending") |
158 | return try | 58 | return fun.find(versions, function(v) |
159 | elseif exists(try .. "/.luarocks-no-project") then | 59 | if util.exists(dir.path(try, ".luarocks", "config-"..v..".lua")) then |
160 | return nil | 60 | detected.project_dir = try |
61 | detected.lua_version = v | ||
62 | return detected | ||
161 | end | 63 | end |
162 | try = try .. "/.." | 64 | end) |
163 | end | ||
164 | end | 65 | end |
165 | 66 | ||
166 | local process_tree_flags | 67 | local process_tree_flags |
@@ -261,19 +162,6 @@ local function process_server_flags(flags) | |||
261 | return true | 162 | return true |
262 | end | 163 | end |
263 | 164 | ||
264 | local function find_lua_version_at(dirname) | ||
265 | local lua_version | ||
266 | for v in util.lua_versions("descending") do | ||
267 | if exists(dir.path(dirname, ".luarocks", "config-"..v..".lua")) then | ||
268 | lua_version = v | ||
269 | break | ||
270 | end | ||
271 | end | ||
272 | return { | ||
273 | lua_version = lua_version | ||
274 | } | ||
275 | end | ||
276 | |||
277 | --- Main command-line processor. | 165 | --- Main command-line processor. |
278 | -- Parses input arguments and calls the appropriate driver function | 166 | -- Parses input arguments and calls the appropriate driver function |
279 | -- to execute the action requested on the command-line, forwarding | 167 | -- to execute the action requested on the command-line, forwarding |
@@ -375,47 +263,65 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
375 | die("Invalid entry for --deps-mode.") | 263 | die("Invalid entry for --deps-mode.") |
376 | end | 264 | end |
377 | 265 | ||
378 | local project_dir | 266 | local detected |
379 | if flags["project-tree"] then | ||
380 | project_dir = flags["project-tree"]:gsub("[/\\][^/\\]+$", "") | ||
381 | end | ||
382 | |||
383 | local lua_data | ||
384 | if flags["lua-dir"] then | 267 | if flags["lua-dir"] then |
385 | local err | 268 | local err |
386 | lua_data, err = cmd.find_lua(flags["lua-dir"], flags["lua-version"]) | 269 | detected, err = util.find_lua(flags["lua-dir"], flags["lua-version"]) |
387 | if not lua_data then | 270 | if not detected then |
388 | die(err) | 271 | die(err) |
389 | end | 272 | end |
273 | assert(detected.lua_version) | ||
274 | assert(detected.lua_dir) | ||
390 | elseif flags["lua-version"] then | 275 | elseif flags["lua-version"] then |
391 | local path_sep = (package.config:sub(1, 1) == "\\" and ";" or ":") | 276 | local path_sep = (package.config:sub(1, 1) == "\\" and ";" or ":") |
392 | for bindir in os.getenv("PATH"):gmatch("[^"..path_sep.."]+") do | 277 | for bindir in os.getenv("PATH"):gmatch("[^"..path_sep.."]+") do |
393 | local parentdir = bindir:gsub("[\\/][^\\/]+[\\/]?$", "") | 278 | local parentdir = bindir:gsub("[\\/][^\\/]+[\\/]?$", "") |
394 | lua_data = cmd.find_lua(dir.path(parentdir), flags["lua-version"]) | 279 | detected = util.find_lua(dir.path(parentdir), flags["lua-version"]) |
395 | if lua_data then | 280 | if detected then |
396 | break | 281 | break |
397 | end | 282 | end |
398 | lua_data = cmd.find_lua(bindir, flags["lua-version"]) | 283 | detected = util.find_lua(bindir, flags["lua-version"]) |
399 | if lua_data then | 284 | if detected then |
400 | break | 285 | break |
401 | end | 286 | end |
402 | end | 287 | end |
403 | if not lua_data then | 288 | if not detected then |
404 | util.warning("Could not find a Lua interpreter for version " .. | 289 | util.warning("Could not find a Lua interpreter for version " .. |
405 | flags["lua-version"] .. " in your PATH. " .. | 290 | flags["lua-version"] .. " in your PATH. " .. |
406 | "Modules may not install with the correct configurations. " .. | 291 | "Modules may not install with the correct configurations. " .. |
407 | "You may want to specify to the path prefix to your build " .. | 292 | "You may want to specify to the path prefix to your build " .. |
408 | "of Lua " .. flags["lua-version"] .. " using --lua-dir") | 293 | "of Lua " .. flags["lua-version"] .. " using --lua-dir") |
409 | lua_data = { | 294 | detected = { |
410 | lua_version = flags["lua-version"], | 295 | lua_version = flags["lua-version"], |
411 | } | 296 | } |
412 | end | 297 | end |
413 | else | 298 | end |
414 | if not project_dir then | 299 | |
415 | project_dir = find_project_dir() | 300 | if flags["project-tree"] then |
301 | local project_tree = flags["project-tree"]:gsub("[/\\][^/\\]+$", "") | ||
302 | detected = detected or { | ||
303 | project_dir = project_tree | ||
304 | } | ||
305 | local d = check_if_config_is_present(detected, project_tree) | ||
306 | if d then | ||
307 | detected = d | ||
308 | else | ||
309 | detected.project_dir = nil | ||
416 | end | 310 | end |
417 | if project_dir then | 311 | else |
418 | lua_data = find_lua_version_at(project_dir) | 312 | detected = detected or {} |
313 | local try = "." | ||
314 | for _ = 1, 10 do -- FIXME detect when root dir was hit instead | ||
315 | if util.exists(try .. "/.luarocks") and util.exists(try .. "/lua_modules") then | ||
316 | local d = check_if_config_is_present(detected, try) | ||
317 | if d then | ||
318 | detected = d | ||
319 | break | ||
320 | end | ||
321 | elseif util.exists(try .. "/.luarocks-no-project") then | ||
322 | break | ||
323 | end | ||
324 | try = try .. "/.." | ||
419 | end | 325 | end |
420 | end | 326 | end |
421 | 327 | ||
@@ -433,16 +339,16 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
433 | end | 339 | end |
434 | 340 | ||
435 | ----------------------------------------------------------------------------- | 341 | ----------------------------------------------------------------------------- |
436 | local ok, err = cfg.init(lua_data, project_dir, util.warning) | 342 | local ok, err = cfg.init(detected, util.warning) |
437 | if not ok then | 343 | if not ok then |
438 | die(err) | 344 | die(err) |
439 | end | 345 | end |
440 | ----------------------------------------------------------------------------- | 346 | ----------------------------------------------------------------------------- |
441 | 347 | ||
442 | fs.init() | 348 | fs.init() |
443 | 349 | ||
444 | if project_dir then | 350 | if detected.project_dir then |
445 | project_dir = fs.absolute_name(project_dir) | 351 | detected.project_dir = fs.absolute_name(detected.project_dir) |
446 | end | 352 | end |
447 | 353 | ||
448 | if flags["version"] then | 354 | if flags["version"] then |
@@ -467,7 +373,7 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
467 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") | 373 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") |
468 | end | 374 | end |
469 | 375 | ||
470 | ok, err = process_tree_flags(flags, project_dir) | 376 | ok, err = process_tree_flags(flags, detected.project_dir) |
471 | if not ok then | 377 | if not ok then |
472 | die(err) | 378 | die(err) |
473 | end | 379 | end |
diff --git a/src/luarocks/core/cfg.lua b/src/luarocks/core/cfg.lua index 5cfa10c3..670f04b2 100644 --- a/src/luarocks/core/cfg.lua +++ b/src/luarocks/core/cfg.lua | |||
@@ -535,8 +535,8 @@ local cfg = {} | |||
535 | 535 | ||
536 | --- Initializes the LuaRocks configuration for variables, paths | 536 | --- Initializes the LuaRocks configuration for variables, paths |
537 | -- and OS detection. | 537 | -- and OS detection. |
538 | -- @param lua_data table containing information pertaining the location | 538 | -- @param detected table containing information detected about the |
539 | -- of Lua in the environment. All fields below are optional: | 539 | -- environment. All fields below are optional: |
540 | -- * lua_version (in x.y format, e.g. "5.3") | 540 | -- * lua_version (in x.y format, e.g. "5.3") |
541 | -- * luajit_version (complete, e.g. "2.1.0-beta3") | 541 | -- * luajit_version (complete, e.g. "2.1.0-beta3") |
542 | -- * lua_bindir (e.g. "/usr/local/bin") | 542 | -- * lua_bindir (e.g. "/usr/local/bin") |
@@ -544,25 +544,25 @@ local cfg = {} | |||
544 | -- * lua_libdir(e.g. "/usr/local/lib") | 544 | -- * lua_libdir(e.g. "/usr/local/lib") |
545 | -- * lua_dir (e.g. "/usr/local") | 545 | -- * lua_dir (e.g. "/usr/local") |
546 | -- * lua_interpreter (e.g. "lua-5.3") | 546 | -- * lua_interpreter (e.g. "lua-5.3") |
547 | -- @param project_dir a string with the path of the project directory | 547 | -- * project_dir (a string with the path of the project directory |
548 | -- when using per-project environments, as created with `luarocks init` | 548 | -- when using per-project environments, as created with `luarocks init`) |
549 | -- @param warning a logging function for warnings that takes a string | 549 | -- @param warning a logging function for warnings that takes a string |
550 | -- @return true on success; nil and an error message on failure. | 550 | -- @return true on success; nil and an error message on failure. |
551 | function cfg.init(lua_data, project_dir, warning) | 551 | function cfg.init(detected, warning) |
552 | lua_data = lua_data or {} | 552 | detected = detected or {} |
553 | 553 | ||
554 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") | 554 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") |
555 | if not hc_ok then | 555 | if not hc_ok then |
556 | hardcoded = {} | 556 | hardcoded = {} |
557 | end | 557 | end |
558 | 558 | ||
559 | local lua_version = lua_data.lua_version or hardcoded.LUA_VERSION or _VERSION:sub(5) | 559 | local lua_version = detected.lua_version or hardcoded.LUA_VERSION or _VERSION:sub(5) |
560 | local luajit_version = lua_data.luajit_version or hardcoded.LUAJIT_VERSION or (jit and jit.version:sub(8)) | 560 | local luajit_version = detected.luajit_version or hardcoded.LUAJIT_VERSION or (jit and jit.version:sub(8)) |
561 | local lua_interpreter = lua_data.lua_interpreter or hardcoded.LUA_INTERPRETER or (arg and arg[-1] and arg[-1]:gsub(".*[\\/]", "")) or (is_windows and "lua.exe" or "lua") | 561 | local lua_interpreter = detected.lua_interpreter or hardcoded.LUA_INTERPRETER or (arg and arg[-1] and arg[-1]:gsub(".*[\\/]", "")) or (is_windows and "lua.exe" or "lua") |
562 | local lua_bindir = lua_data.lua_bindir or hardcoded.LUA_BINDIR or (arg and arg[-1] and arg[-1]:gsub("[\\/][^\\/]+$", "")) | 562 | local lua_bindir = detected.lua_bindir or hardcoded.LUA_BINDIR or (arg and arg[-1] and arg[-1]:gsub("[\\/][^\\/]+$", "")) |
563 | local lua_incdir = lua_data.lua_incdir or hardcoded.LUA_INCDIR | 563 | local lua_incdir = detected.lua_incdir or hardcoded.LUA_INCDIR |
564 | local lua_libdir = lua_data.lua_libdir or hardcoded.LUA_LIBDIR | 564 | local lua_libdir = detected.lua_libdir or hardcoded.LUA_LIBDIR |
565 | local lua_dir = lua_data.lua_dir or hardcoded.LUA_DIR | 565 | local lua_dir = detected.lua_dir or hardcoded.LUA_DIR |
566 | 566 | ||
567 | local init = cfg.init | 567 | local init = cfg.init |
568 | 568 | ||
@@ -638,8 +638,8 @@ function cfg.init(lua_data, project_dir, warning) | |||
638 | local name = "config-"..cfg.lua_version..".lua" | 638 | local name = "config-"..cfg.lua_version..".lua" |
639 | sys_config_file = (cfg.sysconfdir .. "/" .. name):gsub("\\", "/") | 639 | sys_config_file = (cfg.sysconfdir .. "/" .. name):gsub("\\", "/") |
640 | home_config_file = (cfg.homeconfdir .. "/" .. name):gsub("\\", "/") | 640 | home_config_file = (cfg.homeconfdir .. "/" .. name):gsub("\\", "/") |
641 | if project_dir then | 641 | if detected.project_dir then |
642 | project_config_file = project_dir .. "/.luarocks/" .. name | 642 | project_config_file = detected.project_dir .. "/.luarocks/" .. name |
643 | end | 643 | end |
644 | end | 644 | end |
645 | 645 | ||
@@ -682,7 +682,7 @@ function cfg.init(lua_data, project_dir, warning) | |||
682 | end | 682 | end |
683 | 683 | ||
684 | -- finally, use the project-specific config file if any | 684 | -- finally, use the project-specific config file if any |
685 | if project_dir then | 685 | if detected.project_dir then |
686 | project_config_ok, err = load_config_file(cfg, platforms, project_config_file) | 686 | project_config_ok, err = load_config_file(cfg, platforms, project_config_file) |
687 | if err then | 687 | if err then |
688 | return nil, err, "config" | 688 | return nil, err, "config" |
@@ -695,14 +695,14 @@ function cfg.init(lua_data, project_dir, warning) | |||
695 | -- Let's finish up the cfg table. | 695 | -- Let's finish up the cfg table. |
696 | ---------------------------------------- | 696 | ---------------------------------------- |
697 | 697 | ||
698 | -- Settings given via lua_data (i.e. --lua-dir) take precedence over config files: | 698 | -- Settings detected or given via the CLI (i.e. --lua-dir) take precedence over config files: |
699 | cfg.lua_version = lua_data.lua_version or cfg.lua_version | 699 | cfg.lua_version = detected.lua_version or cfg.lua_version |
700 | cfg.luajit_version = lua_data.luajit_version or cfg.luajit_version | 700 | cfg.luajit_version = detected.luajit_version or cfg.luajit_version |
701 | cfg.lua_interpreter = lua_data.lua_interpreter or cfg.lua_interpreter | 701 | cfg.lua_interpreter = detected.lua_interpreter or cfg.lua_interpreter |
702 | cfg.variables.LUA_BINDIR = lua_data.lua_bindir or cfg.variables.LUA_BINDIR or lua_bindir | 702 | cfg.variables.LUA_BINDIR = detected.lua_bindir or cfg.variables.LUA_BINDIR or lua_bindir |
703 | cfg.variables.LUA_INCDIR = lua_data.lua_incdir or cfg.variables.LUA_INCDIR or lua_incdir | 703 | cfg.variables.LUA_INCDIR = detected.lua_incdir or cfg.variables.LUA_INCDIR or lua_incdir |
704 | cfg.variables.LUA_LIBDIR = lua_data.lua_libdir or cfg.variables.LUA_LIBDIR or lua_libdir | 704 | cfg.variables.LUA_LIBDIR = detected.lua_libdir or cfg.variables.LUA_LIBDIR or lua_libdir |
705 | cfg.variables.LUA_DIR = lua_data.lua_dir or cfg.variables.LUA_DIR or lua_dir | 705 | cfg.variables.LUA_DIR = detected.lua_dir or cfg.variables.LUA_DIR or lua_dir |
706 | 706 | ||
707 | -- Build a default list of rocks trees if not given | 707 | -- Build a default list of rocks trees if not given |
708 | if cfg.rocks_trees == nil then | 708 | if cfg.rocks_trees == nil then |
@@ -739,7 +739,7 @@ function cfg.init(lua_data, project_dir, warning) | |||
739 | 739 | ||
740 | function cfg.which_config() | 740 | function cfg.which_config() |
741 | return { | 741 | return { |
742 | project = project_dir and { | 742 | project = detected.project_dir and { |
743 | file = project_config_file, | 743 | file = project_config_file, |
744 | ok = project_config_ok, | 744 | ok = project_config_ok, |
745 | }, | 745 | }, |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 7d7ce921..25c521ea 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
@@ -548,4 +548,113 @@ function util.require_json() | |||
548 | return nil, errmsg | 548 | return nil, errmsg |
549 | end | 549 | end |
550 | 550 | ||
551 | -- A portable version of fs.exists that can be used at early startup, | ||
552 | -- before the platform has been determined and luarocks.fs has been | ||
553 | -- initialized. | ||
554 | function util.exists(file) | ||
555 | local fd, _, code = io.open(file, "r") | ||
556 | if code == 13 then | ||
557 | -- code 13 means "Permission denied" on both Unix and Windows | ||
558 | -- io.open on folders always fails with code 13 on Windows | ||
559 | return true | ||
560 | end | ||
561 | if fd then | ||
562 | fd:close() | ||
563 | return true | ||
564 | end | ||
565 | return false | ||
566 | end | ||
567 | |||
568 | do | ||
569 | local function Q(pathname) | ||
570 | if pathname:match("^.:") then | ||
571 | return pathname:sub(1, 2) .. '"' .. pathname:sub(3) .. '"' | ||
572 | end | ||
573 | return '"' .. pathname .. '"' | ||
574 | end | ||
575 | |||
576 | function util.check_lua_version(lua_exe, luaver) | ||
577 | if not util.exists(lua_exe) then | ||
578 | return nil | ||
579 | end | ||
580 | local lv, err = util.popen_read(Q(lua_exe) .. ' -e "io.write(_VERSION:sub(5))"') | ||
581 | if luaver and luaver ~= lv then | ||
582 | return nil | ||
583 | end | ||
584 | local ljv | ||
585 | if lv == "5.1" then | ||
586 | ljv = util.popen_read(Q(lua_exe) .. ' -e "io.write(tostring(jit and jit.version:sub(8)))"') | ||
587 | if ljv == "nil" then | ||
588 | ljv = nil | ||
589 | end | ||
590 | end | ||
591 | return lv, ljv | ||
592 | end | ||
593 | |||
594 | local find_lua_bindir | ||
595 | do | ||
596 | local exe_suffix = (package.config:sub(1, 1) == "\\" and ".exe" or "") | ||
597 | |||
598 | local function insert_lua_variants(names, luaver) | ||
599 | local variants = { | ||
600 | "lua" .. luaver .. exe_suffix, | ||
601 | "lua" .. luaver:gsub("%.", "") .. exe_suffix, | ||
602 | "lua-" .. luaver .. exe_suffix, | ||
603 | "lua-" .. luaver:gsub("%.", "") .. exe_suffix, | ||
604 | } | ||
605 | for _, name in ipairs(variants) do | ||
606 | names[name] = luaver | ||
607 | table.insert(names, name) | ||
608 | end | ||
609 | end | ||
610 | |||
611 | find_lua_bindir = function(prefix, luaver) | ||
612 | local names = {} | ||
613 | if luaver then | ||
614 | insert_lua_variants(names, luaver) | ||
615 | else | ||
616 | for v in util.lua_variants("descending") do | ||
617 | insert_lua_variants(names, v) | ||
618 | end | ||
619 | end | ||
620 | if luaver == "5.1" or not luaver then | ||
621 | table.insert(names, "luajit" .. exe_suffix) | ||
622 | end | ||
623 | table.insert(names, "lua" .. exe_suffix) | ||
624 | |||
625 | local bindirs = { prefix .. "/bin", prefix } | ||
626 | local tried = {} | ||
627 | for _, d in ipairs(bindirs) do | ||
628 | for _, name in ipairs(names) do | ||
629 | local lua_exe = d .. "/" .. name | ||
630 | table.insert(tried, lua_exe) | ||
631 | local lv, ljv = util.check_lua_version(lua_exe, luaver) | ||
632 | if lv then | ||
633 | return name, d, lv, ljv | ||
634 | end | ||
635 | end | ||
636 | end | ||
637 | return nil, "Lua interpreter not found at " .. prefix .. "\n" .. | ||
638 | "Tried:\t" .. table.concat(tried, "\n\t") | ||
639 | end | ||
640 | end | ||
641 | |||
642 | function util.find_lua(prefix, luaver) | ||
643 | local lua_interpreter, bindir, luajitver | ||
644 | lua_interpreter, bindir, luaver, luajitver = find_lua_bindir(prefix, luaver) | ||
645 | if not lua_interpreter then | ||
646 | return nil, bindir | ||
647 | end | ||
648 | |||
649 | return { | ||
650 | lua_version = luaver, | ||
651 | luajit_version = luajitver, | ||
652 | lua_interpreter = lua_interpreter, | ||
653 | lua_dir = prefix, | ||
654 | lua_bindir = bindir, | ||
655 | } | ||
656 | end | ||
657 | end | ||
658 | |||
551 | return util | 659 | return util |
660 | |||