From 392f67d65a950fcf08a08d10d21e80f359160262 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad <hisham@gobolinux.org> Date: Tue, 19 Jun 2018 00:16:24 -0300 Subject: fs: perform tool detection at runtime (downloader, md5checker) --- src/luarocks/fs/lua.lua | 3 +- src/luarocks/fs/tools.lua | 83 ++++++++++++++++++++++++++++++++------------- src/luarocks/upload/api.lua | 2 +- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index ede7884a..b53ef8cc 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua @@ -712,7 +712,8 @@ function fs_lua.download(url, filename, cache) end if https_err then if not downloader_warning then - util.warning("falling back to "..cfg.downloader.." - install luasec to get native HTTPS support") + local downloader = fs.which_tool("downloader") + util.warning("falling back to "..downloader.." - install luasec to get native HTTPS support") downloader_warning = true end return fs.use_downloader(url, filename, cache) diff --git a/src/luarocks/fs/tools.lua b/src/luarocks/fs/tools.lua index 8419f7d3..671c7ae1 100644 --- a/src/luarocks/fs/tools.lua +++ b/src/luarocks/fs/tools.lua @@ -10,21 +10,54 @@ local vars = cfg.variables local dir_stack = {} ---- Obtain current directory. --- Uses the module's internal directory stack. --- @return string: the absolute pathname of the current directory. -function tools.current_dir() - local current = cfg.cache_pwd - if not current then - local pipe = io.popen(fs.quiet_stderr(fs.Q(vars.PWD))) - current = pipe:read("*l") - pipe:close() - cfg.cache_pwd = current +do + local tool_cache = {} + + local tool_options = { + downloader = { + { var = "CURL", name = "curl" }, + { var = "WGET", name = "wget" }, + }, + md5checker = { + { var = "MD5SUM", name = "md5sum" }, + { var = "OPENSSL", name = "openssl" }, + { var = "MD5", name = "md5", arg = "-v" }, + }, + } + + function tools.which_tool(tooltype) + if tool_cache[tooltype] then + return tool_cache[tooltype] + end + + for _, opt in ipairs(tool_options[tooltype]) do + if fs.is_tool_available(vars[opt.var], opt.name, opt.arg) then + tool_cache[tooltype] = opt.name + break + end + end + return tool_cache[tooltype] end - for _, directory in ipairs(dir_stack) do - current = fs.absolute_name(directory, current) +end + +do + local cache_pwd + --- Obtain current directory. + -- Uses the module's internal directory stack. + -- @return string: the absolute pathname of the current directory. + function tools.current_dir() + local current = cache_pwd + if not current then + local pipe = io.popen(fs.quiet_stderr(fs.Q(vars.PWD))) + current = pipe:read("*l") + pipe:close() + cache_pwd = current + end + for _, directory in ipairs(dir_stack) do + current = fs.absolute_name(directory, current) + end + return current end - return current end --- Change the current directory. @@ -101,9 +134,11 @@ function tools.use_downloader(url, filename, cache) assert(type(filename) == "string" or not filename) filename = fs.absolute_name(filename or dir.base_name(url)) + + local downloader = fs.which_tool("downloader") local ok - if cfg.downloader == "wget" then + if downloader == "wget" then local wget_cmd = fs.Q(vars.WGET).." "..vars.WGETNOCERTFLAG.." --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet " if cfg.connection_timeout and cfg.connection_timeout > 0 then wget_cmd = wget_cmd .. "--timeout="..tostring(cfg.connection_timeout).." --tries=1 " @@ -119,7 +154,7 @@ function tools.use_downloader(url, filename, cache) else ok = fs.execute_quiet(wget_cmd, url) end - elseif cfg.downloader == "curl" then + elseif downloader == "curl" then local curl_cmd = fs.Q(vars.CURL).." "..vars.CURLNOCERTFLAG.." -f -L --user-agent \""..cfg.user_agent.." via curl\" " if cfg.connection_timeout and cfg.connection_timeout > 0 then curl_cmd = curl_cmd .. "--connect-timeout "..tostring(cfg.connection_timeout).." " @@ -144,15 +179,17 @@ local md5_cmd = { -- @param file string: The file to be computed. -- @return string: The MD5 checksum or nil + message function tools.get_md5(file) - local cmd = md5_cmd[cfg.md5checker] - if not cmd then return nil, "no MD5 checker command configured" end - local pipe = io.popen(cmd.." "..fs.Q(fs.absolute_name(file))) - local computed = pipe:read("*l") - pipe:close() - if computed then - computed = computed:match("("..("%x"):rep(32)..")") + local md5checker = fs.which_tool("md5checker") + if md5checker then + local cmd = md5_cmd[md5checker] + local pipe = io.popen(cmd.." "..fs.Q(fs.absolute_name(file))) + local computed = pipe:read("*l") + pipe:close() + if computed then + computed = computed:match("("..("%x"):rep(32)..")") + end + if computed then return computed end end - if computed then return computed end return nil, "Failed to compute MD5 hash for file "..tostring(fs.absolute_name(file)) end diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index f9244258..30857158 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua @@ -143,7 +143,7 @@ function Api:request(url, params, post_params) local json_ok, json = require_json() if not json_ok then return nil, "A JSON library is required for this command. "..json end - if cfg.downloader == "wget" then + if fs.which_tool("downloader") == "wget" then local curl_ok, err = fs.is_tool_available(vars.CURL, "curl") if not curl_ok then return nil, err -- cgit v1.2.3-55-g6feb