From 19e1a1163c9eb929cb6791e324a47a7f0d3f99c3 Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Wed, 15 Aug 2012 14:58:52 +0200 Subject: [PATCH] Fix indentation Signed-off-by: Tobias Ulmer --- generic/e2lib.lua | 2561 +++++++++++++++++++++++---------------------- 1 file changed, 1281 insertions(+), 1280 deletions(-) diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 48efe3a..b664ef8 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -56,44 +56,44 @@ local luafile = require("luafile") local global_config = false e2lib.globals = { - logflags = { - { "v1", true }, -- minimal - { "v2", true }, -- verbose - { "v3", false }, -- verbose-build - { "v4", false } -- tooldebug - }, - log_debug = false, - debug = false, - playground = false, - interactive = arg and (arg[ -1 ] == "-i"), - -- variables initialized in init() - username = nil, - homedir = nil, - hostname = nil, - termwidth = 72, - env = {}, - last_output = false, - tmpdirs = {}, - tmpfiles = {}, - default_projects_server = "projects", - default_project_version = "2", - local_e2_branch = nil, - local_e2_tag = nil, - --- command line arguments that influence global settings are stored here - -- @class table - -- @name cmdline - cmdline = {}, - git_skip_checkout = true, - buildnumber_server_url = nil, - template_path = string.format("%s/templates", buildconfig.SYSCONFDIR), - extension_config = ".e2/extensions", - e2config = ".e2/e2config", - global_interface_version_file = ".e2/global-version", - lock = nil, - logrotate = 5, -- configurable via config.log.logrotate - _version = "e2factory, the emlix embedded build system, version " .. - buildconfig.VERSION, - _licence = [[ + logflags = { + { "v1", true }, -- minimal + { "v2", true }, -- verbose + { "v3", false }, -- verbose-build + { "v4", false } -- tooldebug + }, + log_debug = false, + debug = false, + playground = false, + interactive = arg and (arg[ -1 ] == "-i"), + -- variables initialized in init() + username = nil, + homedir = nil, + hostname = nil, + termwidth = 72, + env = {}, + last_output = false, + tmpdirs = {}, + tmpfiles = {}, + default_projects_server = "projects", + default_project_version = "2", + local_e2_branch = nil, + local_e2_tag = nil, + --- command line arguments that influence global settings are stored here + -- @class table + -- @name cmdline + cmdline = {}, + git_skip_checkout = true, + buildnumber_server_url = nil, + template_path = string.format("%s/templates", buildconfig.SYSCONFDIR), + extension_config = ".e2/extensions", + e2config = ".e2/e2config", + global_interface_version_file = ".e2/global-version", + lock = nil, + logrotate = 5, -- configurable via config.log.logrotate + _version = "e2factory, the emlix embedded build system, version " .. + buildconfig.VERSION, + _licence = [[ e2factory is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -105,10 +105,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program. If not, see . -]], - debuglogfile = nil, - debuglogfilebuffer = {}, +along with this program. If not, see .]], + debuglogfile = nil, + debuglogfilebuffer = {}, } -- Interrupt handling @@ -116,272 +115,272 @@ along with this program. If not, see . -- e2util sets up a SIGINT handler that calls back into this function. function e2lib.interrupt_hook() - e2lib.abort("*interrupted by user*") + e2lib.abort("*interrupted by user*") end --- make sure the environment variables inside the globals table are -- initialized properly, and abort otherwise -- This function always succeeds or aborts. function e2lib.init() - e2lib.log(4, "e2lib.init()") - debug.sethook(e2lib.tracer, "cr") - - e2lib.globals.warn_category = { - WDEFAULT = false, - WDEPRECATED = false, - WOTHER = true, - WPOLICY = false, - WHINT = false, - } - - -- get environment variables - local getenv = { - { name = "HOME", required = true }, - { name = "USER", required = true }, - { name = "EDITOR", required = false, default = "vi" }, - { name = "TERM", required = false, default = "linux" }, - { name = "E2_CONFIG", required = false }, - { name = "TMPDIR", required = false, default = "/tmp" }, - { name = "E2TMPDIR", required = false }, - { name = "COLUMNS", required = false, default = "72" }, - { name = "E2_SSH", required = false }, - { name = "E2_LOCAL_BRANCH", required = false }, - { name = "E2_LOCAL_TAG", required = false }, - } - - local osenv = {} - for _, var in pairs(getenv) do - var.val = os.getenv(var.name) - if var.required and not var.val then - e2lib.abort(string.format("%s is not set in the environment", var.name)) - end - if var.default and not var.val then - var.val = var.default - end - osenv[var.name] = var.val - end - e2lib.globals.osenv = osenv - - -- assign some frequently used environment variables - e2lib.globals.homedir = e2lib.globals.osenv["HOME"] - e2lib.globals.username = e2lib.globals.osenv["USER"] - e2lib.globals.terminal = e2lib.globals.osenv["TERM"] - if e2lib.globals.osenv["E2TMPDIR"] then - e2lib.globals.tmpdir = e2lib.globals.osenv["E2TMPDIR"] - else - e2lib.globals.tmpdir = e2lib.globals.osenv["TMPDIR"] - end - - -- get the host name - e2lib.globals.hostname = e2lib.program_output("hostname") - if not e2lib.globals.hostname then - e2lib.abort("hostname ist not set") - end - - e2lib.globals.lock = lock.new() + e2lib.log(4, "e2lib.init()") + debug.sethook(e2lib.tracer, "cr") + + e2lib.globals.warn_category = { + WDEFAULT = false, + WDEPRECATED = false, + WOTHER = true, + WPOLICY = false, + WHINT = false, + } + + -- get environment variables + local getenv = { + { name = "HOME", required = true }, + { name = "USER", required = true }, + { name = "EDITOR", required = false, default = "vi" }, + { name = "TERM", required = false, default = "linux" }, + { name = "E2_CONFIG", required = false }, + { name = "TMPDIR", required = false, default = "/tmp" }, + { name = "E2TMPDIR", required = false }, + { name = "COLUMNS", required = false, default = "72" }, + { name = "E2_SSH", required = false }, + { name = "E2_LOCAL_BRANCH", required = false }, + { name = "E2_LOCAL_TAG", required = false }, + } + + local osenv = {} + for _, var in pairs(getenv) do + var.val = os.getenv(var.name) + if var.required and not var.val then + e2lib.abort(string.format("%s is not set in the environment", var.name)) + end + if var.default and not var.val then + var.val = var.default + end + osenv[var.name] = var.val + end + e2lib.globals.osenv = osenv + + -- assign some frequently used environment variables + e2lib.globals.homedir = e2lib.globals.osenv["HOME"] + e2lib.globals.username = e2lib.globals.osenv["USER"] + e2lib.globals.terminal = e2lib.globals.osenv["TERM"] + if e2lib.globals.osenv["E2TMPDIR"] then + e2lib.globals.tmpdir = e2lib.globals.osenv["E2TMPDIR"] + else + e2lib.globals.tmpdir = e2lib.globals.osenv["TMPDIR"] + end + + -- get the host name + e2lib.globals.hostname = e2lib.program_output("hostname") + if not e2lib.globals.hostname then + e2lib.abort("hostname ist not set") + end + + e2lib.globals.lock = lock.new() end function e2lib.init2() - local rc, re - local e = err.new("initializing globals (step2)") + local rc, re + local e = err.new("initializing globals (step2)") - -- get the global configuration - local config = e2lib.get_global_config() + -- get the global configuration + local config = e2lib.get_global_config() - -- honour tool customizations from the config file - if config.tools then - for k,v in pairs(config.tools) do - tools.set_tool(k, v.name, v.flags) + -- honour tool customizations from the config file + if config.tools then + for k,v in pairs(config.tools) do + tools.set_tool(k, v.name, v.flags) + end end - end - -- handle E2_SSH environment setting - local ssh = nil - ssh = e2lib.globals.osenv["E2_SSH"] - if ssh then - e2lib.log(3, string.format( - "using ssh command from the E2_SSH environment variable: %s", ssh)) - tools.set_tool("ssh", ssh) - end + -- handle E2_SSH environment setting + local ssh = nil + ssh = e2lib.globals.osenv["E2_SSH"] + if ssh then + e2lib.log(3, string.format( + "using ssh command from the E2_SSH environment variable: %s", ssh)) + tools.set_tool("ssh", ssh) + end - -- initialize the tools library after resetting tools - local rc, re = tools.init() - if not rc then - e2lib.abort(e:cat(re)) - end + -- initialize the tools library after resetting tools + local rc, re = tools.init() + if not rc then + e2lib.abort(e:cat(re)) + end - -- get host system architecture - local host_system_arch, re = e2lib.get_sys_arch() - if not host_system_arch then - e2lib.abort(e:cat(re)) - end + -- get host system architecture + local host_system_arch, re = e2lib.get_sys_arch() + if not host_system_arch then + e2lib.abort(e:cat(re)) + end end local tracer_bl_lua_fn = { - ["xpcall"] = 0, - ["tostring"] = 0, - ["print"] = 0, - ["unpack"] = 0, - ["require"] = 0, - ["getfenv"] = 0, - ["setmetatable"] = 0, - ["next"] = 0, - ["assert"] = 0, - ["tonumber"] = 0, - ["rawequal"] = 0, - ["collectgarbage"] = 0, - ["getmetatable"] = 0, - ["module"] = 0, - ["rawset"] = 0, - ["pcall"] = 0, - ["newproxy"] = 0, - ["type"] = 0, - ["select"] = 0, - ["gcinfo"] = 0, - ["pairs"] = 0, - ["rawget"] = 0, - ["loadstring"] = 0, - ["ipairs"] = 0, - ["dofile"] = 0, - ["setfenv"] = 0, - ["load"] = 0, - ["error"] = 0, - ["loadfile"] = 0, - ["sub"] = 0, - ["upper"] = 0, - ["len"] = 0, - ["gfind"] = 0, - ["rep"] = 0, - ["find"] = 0, - ["match"] = 0, - ["char"] = 0, - ["dump"] = 0, - ["gmatch"] = 0, - ["reverse"] = 0, - ["byte"] = 0, - ["format"] = 0, - ["gsub"] = 0, - ["lower"] = 0, - ["setn"] = 0, - ["insert"] = 0, - ["getn"] = 0, - ["foreachi"] = 0, - ["maxn"] = 0, - ["foreach"] = 0, - ["concat"] = 0, - ["sort"] = 0, - ["remove"] = 0, - ["lines"] = 0, - ["write"] = 0, - ["close"] = 0, - ["flush"] = 0, - ["open"] = 0, - ["output"] = 0, - ["type"] = 0, - ["read"] = 0, - ["input"] = 0, - ["popen"] = 0, - ["tmpfile"] = 0, + ["xpcall"] = 0, + ["tostring"] = 0, + ["print"] = 0, + ["unpack"] = 0, + ["require"] = 0, + ["getfenv"] = 0, + ["setmetatable"] = 0, + ["next"] = 0, + ["assert"] = 0, + ["tonumber"] = 0, + ["rawequal"] = 0, + ["collectgarbage"] = 0, + ["getmetatable"] = 0, + ["module"] = 0, + ["rawset"] = 0, + ["pcall"] = 0, + ["newproxy"] = 0, + ["type"] = 0, + ["select"] = 0, + ["gcinfo"] = 0, + ["pairs"] = 0, + ["rawget"] = 0, + ["loadstring"] = 0, + ["ipairs"] = 0, + ["dofile"] = 0, + ["setfenv"] = 0, + ["load"] = 0, + ["error"] = 0, + ["loadfile"] = 0, + ["sub"] = 0, + ["upper"] = 0, + ["len"] = 0, + ["gfind"] = 0, + ["rep"] = 0, + ["find"] = 0, + ["match"] = 0, + ["char"] = 0, + ["dump"] = 0, + ["gmatch"] = 0, + ["reverse"] = 0, + ["byte"] = 0, + ["format"] = 0, + ["gsub"] = 0, + ["lower"] = 0, + ["setn"] = 0, + ["insert"] = 0, + ["getn"] = 0, + ["foreachi"] = 0, + ["maxn"] = 0, + ["foreach"] = 0, + ["concat"] = 0, + ["sort"] = 0, + ["remove"] = 0, + ["lines"] = 0, + ["write"] = 0, + ["close"] = 0, + ["flush"] = 0, + ["open"] = 0, + ["output"] = 0, + ["type"] = 0, + ["read"] = 0, + ["input"] = 0, + ["popen"] = 0, + ["tmpfile"] = 0, } local tracer_bl_e2_fn = { - -- logging stuff - ["log"] = 0, - ["logf"] = 0, - ["getlog"] = 0, - ["warn"] = 0, - ["warnf"] = 0, - - -- error handling - ["new_error"] = 0, - ["append"] = 0, - ["getcount"] = 0, - - -- lua internals - ["(for generator)"] = 0, + -- logging stuff + ["log"] = 0, + ["logf"] = 0, + ["getlog"] = 0, + ["warn"] = 0, + ["warnf"] = 0, + + -- error handling + ["new_error"] = 0, + ["append"] = 0, + ["getcount"] = 0, + + -- lua internals + ["(for generator)"] = 0, } --- function call tracer -- @param event string: type of event -- @param line line number of event (unused) function e2lib.tracer(event, line) - if event ~= "call" and event ~= "return" then - return - end - - local ftbl = debug.getinfo(2) - if ftbl == nil or ftbl.name == nil then - return - end - - if tracer_bl_lua_fn[ftbl.name] ~= nil then - return - end - - if tracer_bl_e2_fn[ftbl.name] ~= nil then - return - end - - -- approximate module name, not always accurate but good enough - local module - if ftbl.source == nil or ftbl.source == "=[C]" then - module = "C." - else - module = string.match(ftbl.source, "(%w+%.)lua$") - if module == nil then - module = "." - end - end - - if event == "call" then - local out = string.format("%s%s(", module, ftbl.name) - for lo = 1, 10 do - local name, value = debug.getlocal(2, lo) - if name == nil or name == "(*temporary)" then - break - end - if lo > 1 then - out = out .. ", " - end - - if type(value) == "string" then - local svalue = string.sub(value, 0, 800) - if string.len(value) > string.len(svalue) then - svalue = svalue .. "..." - end - - out = string.format("%s%s=\"%s\"", out, name, svalue) - else - out = string.format("%s%s=%s", out, name, tostring(value)) - end - - end - out = out .. ")" - e2lib.log(4, out) - else - e2lib.log(4, string.format("< %s%s", module, ftbl.name)) - end + if event ~= "call" and event ~= "return" then + return + end + + local ftbl = debug.getinfo(2) + if ftbl == nil or ftbl.name == nil then + return + end + + if tracer_bl_lua_fn[ftbl.name] ~= nil then + return + end + + if tracer_bl_e2_fn[ftbl.name] ~= nil then + return + end + + -- approximate module name, not always accurate but good enough + local module + if ftbl.source == nil or ftbl.source == "=[C]" then + module = "C." + else + module = string.match(ftbl.source, "(%w+%.)lua$") + if module == nil then + module = "." + end + end + + if event == "call" then + local out = string.format("%s%s(", module, ftbl.name) + for lo = 1, 10 do + local name, value = debug.getlocal(2, lo) + if name == nil or name == "(*temporary)" then + break + end + if lo > 1 then + out = out .. ", " + end + + if type(value) == "string" then + local svalue = string.sub(value, 0, 800) + if string.len(value) > string.len(svalue) then + svalue = svalue .. "..." + end + + out = string.format("%s%s=\"%s\"", out, name, svalue) + else + out = string.format("%s%s=%s", out, name, tostring(value)) + end + + end + out = out .. ")" + e2lib.log(4, out) + else + e2lib.log(4, string.format("< %s%s", module, ftbl.name)) + end end --- return the output of a program, abort if the call fails -- @param cmd string: the program to call -- @return string: the program output function e2lib.program_output(cmd) - local i = io.popen(cmd) - if not i then - e2lib.abort("invocation of program failed: ", cmd) - end - local input = i:read("*a") - i:close() - return input + local i = io.popen(cmd) + if not i then + e2lib.abort("invocation of program failed: ", cmd) + end + local input = i:read("*a") + i:close() + return input end --- print a warning, composed by concatenating all arguments to a string -- @param ... any number of strings -- @return nil function e2lib.warn(category, ...) - local msg = table.concat({...}) - return e2lib.warnf(category, "%s", msg) + local msg = table.concat({...}) + return e2lib.warnf(category, "%s", msg) end --- print a warning @@ -389,20 +388,20 @@ end -- @param ... arguments required for the format string -- @return nil function e2lib.warnf(category, format, ...) - if (format:len() == 0) or (not format) then - bomb("calling warnf() with zero length format") - end - if type(e2lib.globals.warn_category[category]) ~= "boolean" then - bomb("calling warnf() with invalid warning category") - end - if e2lib.globals.warn_category[category] == true then - local prefix = "Warning: " - if e2lib.globals.log_debug then - prefix = string.format("Warning [%s]: ", category) + if (format:len() == 0) or (not format) then + bomb("calling warnf() with zero length format") end - e2lib.log(1, prefix .. string.format(format, ...)) - end - return nil + if type(e2lib.globals.warn_category[category]) ~= "boolean" then + bomb("calling warnf() with invalid warning category") + end + if e2lib.globals.warn_category[category] == true then + local prefix = "Warning: " + if e2lib.globals.log_debug then + prefix = string.format("Warning [%s]: ", category) + end + e2lib.log(1, prefix .. string.format(format, ...)) + end + return nil end --- exit, cleaning up temporary files and directories. @@ -412,23 +411,23 @@ end -- @param ... an error object, or any number of strings -- @return This function does not return function e2lib.abort(...) - local t = { ... } - local e = t[1] - if e and e.print then - e:print() - else - local msg = table.concat(t) - if msg:len() == 0 then - bomb("calling abort() with zero length message") - end - e2lib.log(1, "Error: " .. msg) - end - e2lib.rmtempdirs() - e2lib.rmtempfiles() - if e2lib.globals.lock then - e2lib.globals.lock:cleanup() - end - os.exit(1) + local t = { ... } + local e = t[1] + if e and e.print then + e:print() + else + local msg = table.concat(t) + if msg:len() == 0 then + bomb("calling abort() with zero length message") + end + e2lib.log(1, "Error: " .. msg) + end + e2lib.rmtempdirs() + e2lib.rmtempfiles() + if e2lib.globals.lock then + e2lib.globals.lock:cleanup() + end + os.exit(1) end --- write a message about an internal error, including a traceback @@ -436,25 +435,25 @@ end -- @param ... any number of strings -- @return This function does not return function e2lib.bomb(...) - local msg = table.concat({...}) - io.stderr:write( - "Internal Error:\n" .. - msg .. "\n" .. - "\n" .. - "You encountered an internal error in the e2 tool.\n" .. - "Please send a description of the problem, including the\n" .. - "stacktrace below to .\n" .. - "If possible include a copy of the project in the bug report.\n" .. - "\n" .. - "Thank you - the e2factory team.\n") - io.stderr:write(debug.traceback().."\n") - os.exit(32) + local msg = table.concat({...}) + io.stderr:write( + "Internal Error:\n" .. + msg .. "\n" .. + "\n" .. + "You encountered an internal error in the e2 tool.\n" .. + "Please send a description of the problem, including the\n" .. + "stacktrace below to .\n" .. + "If possible include a copy of the project in the bug report.\n" .. + "\n" .. + "Thank you - the e2factory team.\n") + io.stderr:write(debug.traceback().."\n") + os.exit(32) end function e2lib.sete2config(file) - e2util.setenv("E2_CONFIG", file, 1) - e2lib.globals.osenv["E2_CONFIG"] = file - e2lib.globals.cmdline["e2-config"] = file + e2util.setenv("E2_CONFIG", file, 1) + e2lib.globals.osenv["E2_CONFIG"] = file + e2lib.globals.cmdline["e2-config"] = file end --- enable or disable logging for level. @@ -462,46 +461,46 @@ end -- @param value bool -- @return nil function e2lib.setlog(level, value) - e2lib.globals.logflags[level][2] = value + e2lib.globals.logflags[level][2] = value end --- get logging setting for level -- @param level number: loglevel -- @return bool function e2lib.getlog(level) - return e2lib.globals.logflags[level][2] + return e2lib.globals.logflags[level][2] end --- return highest loglevel that is enabled -- @return number function e2lib.maxloglevel() - local level = 0 - for i = 1, 4 do - if e2lib.getlog(i) then level = i end - end - return level + local level = 0 + for i = 1, 4 do + if e2lib.getlog(i) then level = i end + end + return level end --- get log flags for calling subtools with the same log settings -- @return string: a string holding command line flags function e2lib.getlogflags() - local logflags = "" - if e2lib.getlog(1) then - logflags = "--v1" - end - if e2lib.getlog(2) then - logflags = logflags .. " --v2" - end - if e2lib.getlog(3) then - logflags = logflags .. " --v3" - end - if e2lib.getlog(4) then - logflags = logflags .. " --v4" - end - if e2lib.globals.log_debug then - logflags = logflags .. " --log-debug" - end - return " " .. logflags + local logflags = "" + if e2lib.getlog(1) then + logflags = "--v1" + end + if e2lib.getlog(2) then + logflags = logflags .. " --v2" + end + if e2lib.getlog(3) then + logflags = logflags .. " --v3" + end + if e2lib.getlog(4) then + logflags = logflags .. " --v4" + end + if e2lib.globals.log_debug then + logflags = logflags .. " --log-debug" + end + return " " .. logflags end --- log to the debug logfile, and log to console if getlog(level) @@ -510,11 +509,11 @@ end -- @param ... additional parameters to pass to string.format -- @return nil function e2lib.logf(level, format, ...) - if not format then - bomb("calling log() without format string") - end - local msg = string.format(format, ...) - return e2lib.log(level, msg) + if not format then + bomb("calling log() without format string") + end + local msg = string.format(format, ...) + return e2lib.log(level, msg) end --- log to the debug logfile, and log to console if getlog(level) @@ -524,111 +523,111 @@ end -- @param ... strings: arguments required for the format string -- @return nil function e2lib.log(level, msg) - if level < 1 or level > 4 then - bomb("invalid log level") - end - if not msg then - bomb("calling log() without log message") - end - local log_prefix = "[" .. level .. "] " - -- remove end of line if it exists - if msg:match("\n$") then - msg = msg:sub(1, msg:len() - 1) - end - - if e2lib.globals.debuglogfile then - - -- write out buffered messages first - for _,m in ipairs(e2lib.globals.debuglogfilebuffer) do - e2lib.globals.debuglogfile:write(m) - end - e2lib.globals.debuglogfilebuffer = {} - - e2lib.globals.debuglogfile:write(log_prefix .. msg .. "\n") - e2lib.globals.debuglogfile:flush() - else - table.insert(e2lib.globals.debuglogfilebuffer, log_prefix .. msg .. "\n") - end - if e2lib.getlog(level) then - if e2lib.globals.log_debug then - io.stderr:write(log_prefix) + if level < 1 or level > 4 then + bomb("invalid log level") + end + if not msg then + bomb("calling log() without log message") + end + local log_prefix = "[" .. level .. "] " + -- remove end of line if it exists + if msg:match("\n$") then + msg = msg:sub(1, msg:len() - 1) + end + + if e2lib.globals.debuglogfile then + + -- write out buffered messages first + for _,m in ipairs(e2lib.globals.debuglogfilebuffer) do + e2lib.globals.debuglogfile:write(m) + end + e2lib.globals.debuglogfilebuffer = {} + + e2lib.globals.debuglogfile:write(log_prefix .. msg .. "\n") + e2lib.globals.debuglogfile:flush() + else + table.insert(e2lib.globals.debuglogfilebuffer, log_prefix .. msg .. "\n") + end + if e2lib.getlog(level) then + if e2lib.globals.log_debug then + io.stderr:write(log_prefix) + end + io.stderr:write(msg .. "\n") end - io.stderr:write(msg .. "\n") - end - return nil + return nil end function e2lib.rotate_log(file) - local e = err.new("rotating logfile: %s", file) - local rc, re - local logdir = e2lib.dirname(file) - local logfile = e2lib.basename(file) - local dir = e2util.directory(logdir, false) - if not dir then - return false, e:cat(string.format("%s: can't read directory", dir)) - end - local files = {} - for _,f in ipairs(dir) do - local match = f:match(string.format("%s.[0-9]+", logfile)) - if match then - table.insert(files, 1, match) - end - end - -- sort in reverse order - local function comp(a, b) - local na = a:match(string.format("%s.([0-9]+)", logfile)) - local nb = b:match(string.format("%s.([0-9]+)", logfile)) - return tonumber(na) > tonumber(nb) - end - table.sort(files, comp) - for _,f in ipairs(files) do - local n = f:match(string.format("%s.([0-9]+)", logfile)) - if n then - n = tonumber(n) - if n >= e2lib.globals.logrotate - 1 then - local del = string.format("%s/%s.%d", logdir, logfile, n) - rc, re = e2lib.rm(del) - if not rc then - return false, e:cat(re) - end - else - local src = string.format("%s/%s.%d", logdir, logfile, n) - local dst = string.format("%s/%s.%d", logdir, logfile, n + 1) - rc, re = e2lib.mv(src, dst) - if not rc then - return false, e:cat(re) - end - end - end - end - local src = file - local dst = string.format("%s/%s.0", logdir, logfile) - if e2lib.isfile(src) then - rc, re = e2lib.mv(src, dst) - if not rc then - return false, e:cat(re) + local e = err.new("rotating logfile: %s", file) + local rc, re + local logdir = e2lib.dirname(file) + local logfile = e2lib.basename(file) + local dir = e2util.directory(logdir, false) + if not dir then + return false, e:cat(string.format("%s: can't read directory", dir)) + end + local files = {} + for _,f in ipairs(dir) do + local match = f:match(string.format("%s.[0-9]+", logfile)) + if match then + table.insert(files, 1, match) + end + end + -- sort in reverse order + local function comp(a, b) + local na = a:match(string.format("%s.([0-9]+)", logfile)) + local nb = b:match(string.format("%s.([0-9]+)", logfile)) + return tonumber(na) > tonumber(nb) end - end - return true, nil + table.sort(files, comp) + for _,f in ipairs(files) do + local n = f:match(string.format("%s.([0-9]+)", logfile)) + if n then + n = tonumber(n) + if n >= e2lib.globals.logrotate - 1 then + local del = string.format("%s/%s.%d", logdir, logfile, n) + rc, re = e2lib.rm(del) + if not rc then + return false, e:cat(re) + end + else + local src = string.format("%s/%s.%d", logdir, logfile, n) + local dst = string.format("%s/%s.%d", logdir, logfile, n + 1) + rc, re = e2lib.mv(src, dst) + if not rc then + return false, e:cat(re) + end + end + end + end + local src = file + local dst = string.format("%s/%s.0", logdir, logfile) + if e2lib.isfile(src) then + rc, re = e2lib.mv(src, dst) + if not rc then + return false, e:cat(re) + end + end + return true, nil end --- exit from the tool, cleaning up temporary files and directories -- @param rc number: return code (optional, defaults to 0) -- @return This function does not return. function e2lib.finish(returncode) - if not returncode then - returncode = 0 - end - local rc, re = plugin.exit_plugins() - if not rc then - e2lib.logf(1, "deinitializing plugins failed (ignoring)") - end - e2lib.rmtempdirs() - e2lib.rmtempfiles() - if e2lib.globals.lock then - e2lib.globals.lock:cleanup() - end - os.exit(returncode) + if not returncode then + returncode = 0 + end + local rc, re = plugin.exit_plugins() + if not rc then + e2lib.logf(1, "deinitializing plugins failed (ignoring)") + end + e2lib.rmtempdirs() + e2lib.rmtempfiles() + if e2lib.globals.lock then + e2lib.globals.lock:cleanup() + end + os.exit(returncode) end @@ -653,75 +652,75 @@ end -- function e2lib.dirname(path) - local s, e, dir = string.find(path, "^(.*)/[^/]*$") - if dir == "" then return "/" - else return dir or "." end + local s, e, dir = string.find(path, "^(.*)/[^/]*$") + if dir == "" then return "/" + else return dir or "." end end function e2lib.basename(path, ext) - local s, e, base = string.find(path, "^.*/([^/]+)[/]?$") - if not base then base = path end - if ext then - if string.sub(base, -#ext) == ext then - return string.sub(base, 1, -#ext - 1) + local s, e, base = string.find(path, "^.*/([^/]+)[/]?$") + if not base then base = path end + if ext then + if string.sub(base, -#ext) == ext then + return string.sub(base, 1, -#ext - 1) + end end - end - return base + return base end function e2lib.splitpath(path) - local p = e2util.realpath(path) - if not p then return nil, "path does not exist" end - local st = e2util.stat(p) - local sf = string.sub(path, -1) ~= "/" - if (st.type == "directory") == sf then - return nil, "is " .. (sf and "" or "not ") .. "a directory" - end - local s, e, d, b = string.find(p, "^(.*/)([^/]*)$") - return d, b == "" and "." or b, st.type + local p = e2util.realpath(path) + if not p then return nil, "path does not exist" end + local st = e2util.stat(p) + local sf = string.sub(path, -1) ~= "/" + if (st.type == "directory") == sf then + return nil, "is " .. (sf and "" or "not ") .. "a directory" + end + local s, e, d, b = string.find(p, "^(.*/)([^/]*)$") + return d, b == "" and "." or b, st.type end function e2lib.is_backup_file(path) - return string.find(path, "~$") or string.find(path, "^#.*#$") + return string.find(path, "~$") or string.find(path, "^#.*#$") end function e2lib.chomp(str, chr) - local chr = chr or "/" - if string.sub(str, -1, -1) == chr then - return string.sub(str, 1, -2) - else - return str - end + local chr = chr or "/" + if string.sub(str, -1, -1) == chr then + return string.sub(str, 1, -2) + else + return str + end end --- quotes a string so it can be safely passed to a shell -- @param str string to quote -- @return quoted string function e2lib.shquote(str) - assert(type(str) == "string") + assert(type(str) == "string") - str = string.gsub(str, "'", "'\"'\"'") - return "'"..str.."'" + str = string.gsub(str, "'", "'\"'\"'") + return "'"..str.."'" end -- determines the type of an archive -- say "z" for gzip, "j" for bzip2, "" for tar archive -- nil is returned for unknown data function e2lib.tartype(path) - local f, e = io.open(path, "r") - if not f then - e2lib.abort(e) - end - local d = f and f:read(512) - local l = d and string.len(d) or 0 - local c = nil - f:close() - if l > 261 and string.sub(d, 258, 262) == "ustar" then c = "" - elseif l > 1 and string.sub(d, 1, 2) == "\031\139" then c = "--gzip" - elseif l > 2 and string.sub(d, 1, 3) == "BZh" then c = "--bzip2" - elseif l > 3 and string.sub(d, 1, 4) == "PK\003\004" then c = "zip" - end - return c + local f, e = io.open(path, "r") + if not f then + e2lib.abort(e) + end + local d = f and f:read(512) + local l = d and string.len(d) or 0 + local c = nil + f:close() + if l > 261 and string.sub(d, 258, 262) == "ustar" then c = "" + elseif l > 1 and string.sub(d, 1, 2) == "\031\139" then c = "--gzip" + elseif l > 2 and string.sub(d, 1, 3) == "BZh" then c = "--bzip2" + elseif l > 3 and string.sub(d, 1, 4) == "PK\003\004" then c = "zip" + end + return c end --- translate filename suffixes to valid tartypes for e2-su-2.2 @@ -729,18 +728,18 @@ end -- @return string: tartype, or nil on failure -- @return an error object on failure function e2lib.tartype_by_suffix(filename) - local tartype - if filename:match("tgz$") or filename:match("tar.gz$") then - tartype = "tar.gz" - elseif filename:match("tar.bz2$") then - tartype = "tar.bz2" - elseif filename:match("tar$") then - tartype = "tar" - else - e = err.new("unknown suffix for filename: %s", filename) - return false, e - end - return tartype + local tartype + if filename:match("tgz$") or filename:match("tar.gz$") then + tartype = "tar.gz" + elseif filename:match("tar.bz2$") then + tartype = "tar.bz2" + elseif filename:match("tar$") then + tartype = "tar" + else + e = err.new("unknown suffix for filename: %s", filename) + return false, e + end + return tartype end -- generates a command to unpack an archive file @@ -749,13 +748,13 @@ end -- destdir is the path to where the unpacked files shall be put -- return unix command on success, nil otherwise function e2lib.howtounpack(physpath, virtpath, destdir) - local c = e2lib.tartype(physpath) - if c == "zip" then - c = "unzip \"" .. virtpath .. "\" -d \"" .. destdir .. "\"" - elseif c then - c = string.format("tar -C '%s' %s -xf '%s'", destdir, c, virtpath) - end - return c + local c = e2lib.tartype(physpath) + if c == "zip" then + c = "unzip \"" .. virtpath .. "\" -d \"" .. destdir .. "\"" + elseif c then + c = string.format("tar -C '%s' %s -xf '%s'", destdir, c, virtpath) + end + return c end -- Input/Output operations @@ -770,28 +769,28 @@ end -- specifies the size of subsequently read blocks and defaults to 1024. function e2lib.read_line(path) - local f, msg = io.open(path) - if not f then - return nil, err.new("%s", msg) - end - local l, msg = f:read("*l") - if not l then - return nil, err.new("%s", msg) - end - f:close() - return l + local f, msg = io.open(path) + if not f then + return nil, err.new("%s", msg) + end + local l, msg = f:read("*l") + if not l then + return nil, err.new("%s", msg) + end + f:close() + return l end function e2lib.read_all(fd, blocksize) - local input = {} - local blocksize = blocksize or 1024 - while true do - local s, msg = e2util.read(fd, blocksize) - if not s then bomb("read error: ", msg) - elseif #s == 0 then break - else table.insert(input, s) end - end - return table.concat(input) + local input = {} + local blocksize = blocksize or 1024 + while true do + local s, msg = e2util.read(fd, blocksize) + if not s then bomb("read error: ", msg) + elseif #s == 0 then break + else table.insert(input, s) end + end + return table.concat(input) end @@ -811,24 +810,24 @@ end -- are also included in the listing. function e2lib.read_configuration(p) - if e2util.exists(p) then - local function nextline(s) - while true do - local ln = s:read("*l") - if not ln then - s:close() - return nil - elseif not string.find(ln, "^%s*#") and string.find(ln, "%S") then - local s = string.find(ln, "#.*") - if s then return string.sub(ln, 1, s - 1) - else return ln end - end - end - end - return nextline, io.open(p) - else - e2lib.abort("no such file: " .. p) - end + if e2util.exists(p) then + local function nextline(s) + while true do + local ln = s:read("*l") + if not ln then + s:close() + return nil + elseif not string.find(ln, "^%s*#") and string.find(ln, "%S") then + local s = string.find(ln, "#.*") + if s then return string.sub(ln, 1, s - 1) + else return ln end + end + end + end + return nextline, io.open(p) + else + e2lib.abort("no such file: " .. p) + end end --- read the global config file @@ -838,76 +837,76 @@ end -- @return bool -- @return error string on error function e2lib.read_global_config(e2_config_file) - e2lib.log(4, "read_global_config()") - local cf = e2lib.get_first_val({ - e2lib.globals.cmdline["e2-config"], -- command line - e2lib.globals.osenv["E2_CONFIG"], -- environment - }) - local cf_path - if cf then - cf_path = { cf } - elseif e2_config_file then - cf_path = { e2_config_file } - else - cf_path = { - -- this is ordered by priority - string.format("%s/.e2/e2.conf-%s.%s.%s", e2lib.globals.homedir, - buildconfig.MAJOR, buildconfig.MINOR, buildconfig.PATCHLEVEL), - string.format("%s/.e2/e2.conf-%s.%s", e2lib.globals.homedir, buildconfig.MAJOR, - buildconfig.MINOR), - string.format("%s/.e2/e2.conf", e2lib.globals.homedir), - string.format("%s/e2.conf-%s.%s.%s", buildconfig.SYSCONFDIR, - buildconfig.MAJOR, buildconfig.MINOR, buildconfig.PATCHLEVEL), - string.format("%s/e2.conf-%s.%s", buildconfig.SYSCONFDIR, - buildconfig.MAJOR, buildconfig.MINOR), - string.format("%s/e2.conf", buildconfig.SYSCONFDIR), - } - end - -- use ipairs to keep the list entries ordered - for _,path in ipairs(cf_path) do - local c = {} - c.config = function(x) - c.data = x - end - e2lib.log(4, string.format("reading global config file: %s", path)) - local rc = e2util.exists(path) - if rc then - e2lib.log(3, string.format("using global config file: %s", path)) - local rc, e = e2lib.dofile_protected(path, c, true) - if not rc then - return nil, e - end - if not c.data then - return false, "invalid configuration" - end - global_config = c.data - e2lib.use_global_config() - return true, nil + e2lib.log(4, "read_global_config()") + local cf = e2lib.get_first_val({ + e2lib.globals.cmdline["e2-config"], -- command line + e2lib.globals.osenv["E2_CONFIG"], -- environment + }) + local cf_path + if cf then + cf_path = { cf } + elseif e2_config_file then + cf_path = { e2_config_file } else - e2lib.log(4, string.format( - "global config file does not exist: %s", path)) + cf_path = { + -- this is ordered by priority + string.format("%s/.e2/e2.conf-%s.%s.%s", e2lib.globals.homedir, + buildconfig.MAJOR, buildconfig.MINOR, buildconfig.PATCHLEVEL), + string.format("%s/.e2/e2.conf-%s.%s", e2lib.globals.homedir, buildconfig.MAJOR, + buildconfig.MINOR), + string.format("%s/.e2/e2.conf", e2lib.globals.homedir), + string.format("%s/e2.conf-%s.%s.%s", buildconfig.SYSCONFDIR, + buildconfig.MAJOR, buildconfig.MINOR, buildconfig.PATCHLEVEL), + string.format("%s/e2.conf-%s.%s", buildconfig.SYSCONFDIR, + buildconfig.MAJOR, buildconfig.MINOR), + string.format("%s/e2.conf", buildconfig.SYSCONFDIR), + } + end + -- use ipairs to keep the list entries ordered + for _,path in ipairs(cf_path) do + local c = {} + c.config = function(x) + c.data = x + end + e2lib.log(4, string.format("reading global config file: %s", path)) + local rc = e2util.exists(path) + if rc then + e2lib.log(3, string.format("using global config file: %s", path)) + local rc, e = e2lib.dofile_protected(path, c, true) + if not rc then + return nil, e + end + if not c.data then + return false, "invalid configuration" + end + global_config = c.data + e2lib.use_global_config() + return true, nil + else + e2lib.log(4, string.format( + "global config file does not exist: %s", path)) + end end - end - return false, "no config file available" + return false, "no config file available" end function e2lib.write_extension_config(extensions) - local e = err.new("writing extensions config: %s", e2lib.globals.extension_config) - local f, re = io.open(e2lib.globals.extension_config, "w") - if not f then - return false, e:cat(re) - end - f:write(string.format("extensions {\n")) - for _,ex in ipairs(extensions) do - f:write(string.format(" {\n")) - for k,v in pairs(ex) do - f:write(string.format(" %s=\"%s\",\n", k, v)) - end - f:write(string.format(" },\n")) - end - f:write(string.format("}\n")) - f:close() - return true, nil + local e = err.new("writing extensions config: %s", e2lib.globals.extension_config) + local f, re = io.open(e2lib.globals.extension_config, "w") + if not f then + return false, e:cat(re) + end + f:write(string.format("extensions {\n")) + for _,ex in ipairs(extensions) do + f:write(string.format(" {\n")) + for k,v in pairs(ex) do + f:write(string.format(" %s=\"%s\",\n", k, v)) + end + f:write(string.format(" },\n")) + end + f:write(string.format("}\n")) + f:close() + return true, nil end --- read the local extension configuration @@ -916,26 +915,26 @@ end -- @return the extension configuration table -- @return an error object on failure function e2lib.read_extension_config() - local e = err.new("reading extension config file: %s", - e2lib.globals.extension_config) - local rc = e2util.exists(e2lib.globals.extension_config) - if not rc then - return false, e:append("config file does not exist") - end - e2lib.logf(3, "reading extension file: %s", e2lib.globals.extension_config) - local c = {} - c.extensions = function(x) - c.data = x - end - local rc, re = e2lib.dofile_protected(e2lib.globals.extension_config, c, true) - if not rc then - return false, e:cat(re) - end - local extension = c.data - if not extension then - return false, e:append("invalid extension configuration") - end - return extension, nil + local e = err.new("reading extension config file: %s", + e2lib.globals.extension_config) + local rc = e2util.exists(e2lib.globals.extension_config) + if not rc then + return false, e:append("config file does not exist") + end + e2lib.logf(3, "reading extension file: %s", e2lib.globals.extension_config) + local c = {} + c.extensions = function(x) + c.data = x + end + local rc, re = e2lib.dofile_protected(e2lib.globals.extension_config, c, true) + if not rc then + return false, e:cat(re) + end + local extension = c.data + if not extension then + return false, e:append("invalid extension configuration") + end + return extension, nil end --- use the global parameters from the global configuration @@ -943,68 +942,68 @@ end -- @return nothing function e2lib.use_global_config() - -- check if type(x) == t, and abort if not. - local function assert_type(x, d, t1) - local t2 = type(x) - if t1 ~= t2 then - e2lib.abort( - string.format("configuration error: %s (expected %s got %s)", d, t1, t2)) - end - end - - local config = global_config - if not config then - e2lib.abort("global config not available") - end - if config.log then - assert_type(config.log, "config.log", "table") - if config.log.logrotate then - assert_type(config.log.logrotate, "config.log.logrotate", "number") - e2lib.globals.logrotate = config.log.logrotate - end - end - if config.site and config.site.buildnumber_server_url ~= nil then - e2lib.globals.buildnumber_server_url = config.site.buildnumber_server_url - e2lib.log(3, string.format("e2lib.globals.buildnumber_server_url=%s", - tostring(config.site.buildnumber_server_url))) - end - assert_type(config.site, "config.site", "table") - assert_type(config.site.e2_branch, "config.site.e2_branch", "string") - assert_type(config.site.e2_tag, "config.site.e2_tag", "string") - assert_type(config.site.e2_server, "config.site.e2_server", "string") - assert_type(config.site.e2_base, "config.site.e2_base", "string") - assert_type(config.site.default_extensions, "config.site.default_extensions", "table") + -- check if type(x) == t, and abort if not. + local function assert_type(x, d, t1) + local t2 = type(x) + if t1 ~= t2 then + e2lib.abort( + string.format("configuration error: %s (expected %s got %s)", d, t1, t2)) + end + end + + local config = global_config + if not config then + e2lib.abort("global config not available") + end + if config.log then + assert_type(config.log, "config.log", "table") + if config.log.logrotate then + assert_type(config.log.logrotate, "config.log.logrotate", "number") + e2lib.globals.logrotate = config.log.logrotate + end + end + if config.site and config.site.buildnumber_server_url ~= nil then + e2lib.globals.buildnumber_server_url = config.site.buildnumber_server_url + e2lib.log(3, string.format("e2lib.globals.buildnumber_server_url=%s", + tostring(config.site.buildnumber_server_url))) + end + assert_type(config.site, "config.site", "table") + assert_type(config.site.e2_branch, "config.site.e2_branch", "string") + assert_type(config.site.e2_tag, "config.site.e2_tag", "string") + assert_type(config.site.e2_server, "config.site.e2_server", "string") + assert_type(config.site.e2_base, "config.site.e2_base", "string") + assert_type(config.site.default_extensions, "config.site.default_extensions", "table") end --- get the global configuration -- this function always succeeds or aborts -- @return the global configuration function e2lib.get_global_config() - local config = global_config - if not config then - e2lib.abort("global config not available") - end - return config + local config = global_config + if not config then + e2lib.abort("global config not available") + end + return config end function e2lib.directory(p, dotfiles, noerror) - local dir = e2util.directory(p, dotfiles) - if not dir then - if noerror then dir = {} - else e2lib.abort("directory `", p, "' does not exist") - end - end - table.sort(dir) - local i = 1 - local function nextfile(s) - if i > #s then return nil - else - local j = i - i = i + 1 - return s[ j ] + local dir = e2util.directory(p, dotfiles) + if not dir then + if noerror then dir = {} + else e2lib.abort("directory `", p, "' does not exist") + end end - end - return nextfile, dir + table.sort(dir) + local i = 1 + local function nextfile(s) + if i > #s then return nil + else + local j = i + i = i + 1 + return s[ j ] + end + end + return nextfile, dir end @@ -1017,40 +1016,40 @@ end -- compute_hash(ITER, [VALUE...]) function e2lib.compute_hash(iter, ...) - local n, f, s - local i, o, e, p = e2util.pipe("sha1sum") - if not i then bomb("cannot calculate hash sum: " .. o) end - for x in iter(...) do - n, f = e2util.write(i, x) + local n, f, s + local i, o, e, p = e2util.pipe("sha1sum") + if not i then bomb("cannot calculate hash sum: " .. o) end + for x in iter(...) do + n, f = e2util.write(i, x) + if not n then bomb(f) end + end + n, f = e2util.close(i) + if not n then bomb(f) end + s, f = e2util.read(o, 40) + if not s then bomb(f) end + n, f = e2util.close(o) if not n then bomb(f) end - end - n, f = e2util.close(i) - if not n then bomb(f) end - s, f = e2util.read(o, 40) - if not s then bomb(f) end - n, f = e2util.close(o) - if not n then bomb(f) end - n, f = e2util.wait(p) - if not n then bomb(f) end - return s + n, f = e2util.wait(p) + if not n then bomb(f) end + return s end -- callcmd: call a command, connecting -- stdin, stdout, stderr to luafile objects function e2lib.callcmd(infile, outfile, errfile, cmd) - -- redirect stdin - io.stdin:close() - luafile.dup2(infile:fileno(), 0) - -- redirect stdout - io.stdout:close() - luafile.dup2(outfile:fileno(), 1) - -- redirect stderr - io.stderr:close() - luafile.dup2(errfile:fileno(), 2) - -- run the command - local rc = os.execute(cmd) - return (rc/256) + -- redirect stdin + io.stdin:close() + luafile.dup2(infile:fileno(), 0) + -- redirect stdout + io.stdout:close() + luafile.dup2(outfile:fileno(), 1) + -- redirect stderr + io.stderr:close() + luafile.dup2(errfile:fileno(), 2) + -- run the command + local rc = os.execute(cmd) + return (rc/256) end -- callcmd_redirect: call a command with @@ -1058,18 +1057,18 @@ end -- stdout/stderr redirected to a luafile object function e2lib.callcmd_redirect(cmd, out) - local devnull, pid, rc - devnull = luafile.open("/dev/null", "r") - e2lib.log(3, "+ " .. cmd) - pid = e2util.fork() - if pid == 0 then - rc = e2lib.callcmd(devnull, out, out, cmd) - os.exit(rc) - else - rc = e2util.wait(pid) - luafile.close(devnull) - return rc - end + local devnull, pid, rc + devnull = luafile.open("/dev/null", "r") + e2lib.log(3, "+ " .. cmd) + pid = e2util.fork() + if pid == 0 then + rc = e2lib.callcmd(devnull, out, out, cmd) + os.exit(rc) + else + rc = e2util.wait(pid) + luafile.close(devnull) + return rc + end end -- callcmd_pipe: call several commands in a pipe @@ -1078,77 +1077,77 @@ end -- return nil on success, descriptive string on error function e2lib.callcmd_pipe(cmds, infile, outfile) - local i = infile or luafile.open("/dev/null", "r") - local c = #cmds - local rc = nil - local rcs = {} - local pids = {} - local ers = {} - for n = 1, c do - local o, pr, fr, er, ew - pr, er, ew = luafile.pipe() - if not pr then e2lib.abort("failed to open pipe (error)") end - if n < c then - pr, fr, o = luafile.pipe() - if not pr then e2lib.abort("failed to open pipe") end - else - o = outfile or ew + local i = infile or luafile.open("/dev/null", "r") + local c = #cmds + local rc = nil + local rcs = {} + local pids = {} + local ers = {} + for n = 1, c do + local o, pr, fr, er, ew + pr, er, ew = luafile.pipe() + if not pr then e2lib.abort("failed to open pipe (error)") end + if n < c then + pr, fr, o = luafile.pipe() + if not pr then e2lib.abort("failed to open pipe") end + else + o = outfile or ew + end + e2lib.log(3, "+ " .. cmds[n]) + local pid = e2util.fork() + if pid == 0 then + if n < c then fr:close() end + er:close() + rc = e2lib.callcmd(i, o, ew, cmds[n]) + os.exit(rc) + end + pids[pid] = n + e2util.unblock(er:fileno()) + ers[n] = er + ew:close() + if n < c then o:close() end + if n > 1 or not infile then i:close() end + i = fr end - e2lib.log(3, "+ " .. cmds[n]) - local pid = e2util.fork() - if pid == 0 then - if n < c then fr:close() end - er:close() - rc = e2lib.callcmd(i, o, ew, cmds[n]) - os.exit(rc) - end - pids[pid] = n - e2util.unblock(er:fileno()) - ers[n] = er - ew:close() - if n < c then o:close() end - if n > 1 or not infile then i:close() end - i = fr - end - while c > 0 do - local fds = {} - local ifd = {} - for i, f in pairs(ers) do - local n = f:fileno() - table.insert(fds, n) - ifd[n] = i - end - local i, r = e2util.poll(-1, fds) - if i <= 0 then e2lib.abort("fatal poll abort " .. tostring(i)) end - i = ifd[fds[i]] - if r then - local x - repeat - x = ers[i]:readline() - if x then - e2lib.log(3, x) + while c > 0 do + local fds = {} + local ifd = {} + for i, f in pairs(ers) do + local n = f:fileno() + table.insert(fds, n) + ifd[n] = i end - until not x - else - ers[i]:close() - ers[i] = nil - c = c - 1 - end - end - c = #cmds - while c > 0 do - local r, p = e2util.wait(-1) - if not r then e2lib.abort(p) end - local n = pids[p] - if n then - if r ~= 0 then rc = rc or r end - rcs[n] = r - pids[p] = nil - c = c - 1 - end - end - return rc and "failed to execute commands in a pipe, exit codes are: " - .. table.concat(rcs, ", ") + local i, r = e2util.poll(-1, fds) + if i <= 0 then e2lib.abort("fatal poll abort " .. tostring(i)) end + i = ifd[fds[i]] + if r then + local x + repeat + x = ers[i]:readline() + if x then + e2lib.log(3, x) + end + until not x + else + ers[i]:close() + ers[i] = nil + c = c - 1 + end + end + c = #cmds + while c > 0 do + local r, p = e2util.wait(-1) + if not r then e2lib.abort(p) end + local n = pids[p] + if n then + if r ~= 0 then rc = rc or r end + rcs[n] = r + pids[p] = nil + c = c - 1 + end + end + return rc and "failed to execute commands in a pipe, exit codes are: " + .. table.concat(rcs, ", ") end --- call a command with stdin redirected from /dev/null, stdout/stderr @@ -1157,41 +1156,41 @@ end -- is captured from the pipe. -- @return unknown function e2lib.callcmd_capture(cmd, capture) - local rc, oread, owrite, devnull, pid - local function autocapture(...) - local msg = table.concat({...}) - e2lib.log(3, msg) - e2lib.globals.last_output = msg - end - e2lib.globals.last_output = false - capture = capture or autocapture - rc, oread, owrite = luafile.pipe() - owrite:setlinebuf() - oread:setlinebuf() - devnull = luafile.open("/dev/null", "r") - e2lib.log(4, "+ " .. cmd) - pid = e2util.fork() - if pid == 0 then - oread:close() - rc = e2lib.callcmd(devnull, owrite, owrite, cmd) - os.exit(rc) - else - owrite:close() - --log("capturing...") - while not oread:eof() do - local x = oread:readline() - if x then - --print("read: '" .. x .. "'") - capture(x) - end - end - oread:close() - rc = e2util.wait(pid) - luafile.close(devnull) - --log("capturing done...") - --log("exit status was " .. rc) - end - return rc + local rc, oread, owrite, devnull, pid + local function autocapture(...) + local msg = table.concat({...}) + e2lib.log(3, msg) + e2lib.globals.last_output = msg + end + e2lib.globals.last_output = false + capture = capture or autocapture + rc, oread, owrite = luafile.pipe() + owrite:setlinebuf() + oread:setlinebuf() + devnull = luafile.open("/dev/null", "r") + e2lib.log(4, "+ " .. cmd) + pid = e2util.fork() + if pid == 0 then + oread:close() + rc = e2lib.callcmd(devnull, owrite, owrite, cmd) + os.exit(rc) + else + owrite:close() + --log("capturing...") + while not oread:eof() do + local x = oread:readline() + if x then + --print("read: '" .. x .. "'") + capture(x) + end + end + oread:close() + rc = e2util.wait(pid) + luafile.close(devnull) + --log("capturing done...") + --log("exit status was " .. rc) + end + return rc end --- call a command, log its output to a loglevel, catch the last line of @@ -1201,16 +1200,16 @@ end -- @return number: the return code -- @return string: the program output, or nil function e2lib.callcmd_log(cmd, loglevel) - local e = "" - if not loglevel then - loglevel = 3 - end - local function logto(output) - e2lib.log(loglevel, output) - e = e .. output - end - local rc = e2lib.callcmd_capture(cmd, logto) - return rc, e + local e = "" + if not loglevel then + loglevel = 3 + end + local function logto(output) + e2lib.log(loglevel, output) + e = e .. output + end + local rc = e2lib.callcmd_capture(cmd, logto) + return rc, e end -- Protected execution of Lua code @@ -1222,45 +1221,45 @@ end -- is given and true, then the code may define new global variables. function e2lib.dofile_protected(path, gtable, allownewdefs) - local chunk, msg = loadfile(path) - if not chunk then - return false, msg - end - local t = gtable - -- t._G = t - local function checkread(t, k) - local x = rawget(t, k) - if x then return x - else e2lib.abort(path, ": attempt to reference undefined global variable '", - k, "'") - end - end - local function checkwrite(t, k, v) - e2lib.abort(path, ": attempt to set new global variable `", k, "' to ", v) - end - if not allownewdefs then - setmetatable(t, { __newindex = checkwrite, __index = checkread }) - end - setfenv(chunk, t) - local s, msg = pcall(chunk) - if not s then - e2lib.abort(msg) - end - return true, nil + local chunk, msg = loadfile(path) + if not chunk then + return false, msg + end + local t = gtable + -- t._G = t + local function checkread(t, k) + local x = rawget(t, k) + if x then return x + else e2lib.abort(path, ": attempt to reference undefined global variable '", + k, "'") + end + end + local function checkwrite(t, k, v) + e2lib.abort(path, ": attempt to set new global variable `", k, "' to ", v) + end + if not allownewdefs then + setmetatable(t, { __newindex = checkwrite, __index = checkread }) + end + setfenv(chunk, t) + local s, msg = pcall(chunk) + if not s then + e2lib.abort(msg) + end + return true, nil end function e2lib.dofile2(path, gtable) - local e = err.new("error loading config file: %s", path) - local chunk, msg = loadfile(path) - if not chunk then - return false, e:cat(msg) - end - setfenv(chunk, gtable) - local s, msg = pcall(chunk) - if not s then - return false, e:cat(msg) - end - return true, nil + local e = err.new("error loading config file: %s", path) + local chunk, msg = loadfile(path) + if not chunk then + return false, e:cat(msg) + end + setfenv(chunk, gtable) + local s, msg = pcall(chunk) + if not s then + return false, e:cat(msg) + end + return true, nil end -- locate_project_root([PATH]) -> PATH | nil @@ -1271,85 +1270,85 @@ end -- function e2lib.locate_project_root(path) - local rc, re - local e = err.new("checking for project directory failed") - local save_path = e2util.cwd() - if not save_path then - return nil, e:append("cannot get current working directory") - end - if path then - rc = e2lib.chdir(path) - if not rc then - e2lib.chdir(save_path) - return nil, e:cat(re) - end - else - path = e2util.cwd() - if not path then - e2lib.chdir(save_path) - return nil, e:append("cannot get current working directory") - end - end - while true do - if e2util.exists(".e2") then - e2lib.logf(3, "project is located in: %s", path) - e2lib.chdir(save_path) - return path - end - if path == "/" then - break - end - rc = e2lib.chdir("..") - if not rc then - e2lib.chdir(save_path) - return nil, e:cat(re) + local rc, re + local e = err.new("checking for project directory failed") + local save_path = e2util.cwd() + if not save_path then + return nil, e:append("cannot get current working directory") end - path = e2util.cwd() - if not path then - e2lib.chdir(save_path) - return nil, e:append("cannot get current working directory") + if path then + rc = e2lib.chdir(path) + if not rc then + e2lib.chdir(save_path) + return nil, e:cat(re) + end + else + path = e2util.cwd() + if not path then + e2lib.chdir(save_path) + return nil, e:append("cannot get current working directory") + end + end + while true do + if e2util.exists(".e2") then + e2lib.logf(3, "project is located in: %s", path) + e2lib.chdir(save_path) + return path + end + if path == "/" then + break + end + rc = e2lib.chdir("..") + if not rc then + e2lib.chdir(save_path) + return nil, e:cat(re) + end + path = e2util.cwd() + if not path then + e2lib.chdir(save_path) + return nil, e:append("cannot get current working directory") + end end - end - e2lib.chdir(save_path) - return nil, err.new("not in a project directory") + e2lib.chdir(save_path) + return nil, err.new("not in a project directory") end -- parse version files: function e2lib.parse_versionfile(filename) - local f = luafile.open(filename, "r") - if not f then - e2lib.abort("can't open version file: " .. filename) - end - local l = f:readline() - if not l then - e2lib.abort("can't parse version file: " .. filename) - end - local v = l:match("[0-9]+") - if not v then - e2lib.abort("invalid format of project version `" .. l .. "' in " .. filename) - end - --log(4, "project version is " .. v) - return v + local f = luafile.open(filename, "r") + if not f then + e2lib.abort("can't open version file: " .. filename) + end + local l = f:readline() + if not l then + e2lib.abort("can't parse version file: " .. filename) + end + local v = l:match("[0-9]+") + if not v then + e2lib.abort("invalid format of project version `" .. l .. "' in " .. filename) + end + --log(4, "project version is " .. v) + return v end function e2lib.parse_e2versionfile(filename) - local f = luafile.open(filename, "r") - if not f then - e2lib.abort("can't open e2version file: " .. filename) - end - local l = f:readline() - if not l then - e2lib.abort("can't parse e2version file: " .. filename) - end - local match = l:gmatch("[^%s]+") - local v = {} - v.branch = match() or e2lib.abort("invalid branch name `", l, "' in e2 version file ", - filename) - v.tag = match() or e2lib.abort("invalid tag name `", l, "' in e2 version file ", - filename) - e2lib.log(3, "using e2 branch " .. v.branch .. " tag " .. v.tag) - return v + local f = luafile.open(filename, "r") + if not f then + e2lib.abort("can't open e2version file: " .. filename) + end + local l = f:readline() + if not l then + e2lib.abort("can't parse e2version file: " .. filename) + end + local match = l:gmatch("[^%s]+") + local v = {} + v.branch = match() or e2lib.abort("invalid branch name `", l, "' in e2 version file ", + filename) + v.tag = match() or e2lib.abort("invalid tag name `", l, "' in e2 version file ", + filename) + e2lib.log(3, "using e2 branch " .. v.branch .. " tag " .. v.tag) + return v end --- Create a temporary file. @@ -1359,24 +1358,24 @@ end -- @param template string: template name (optional) -- @return string: name of the file function e2lib.mktempfile(template) - if not template then - template = string.format("%s/e2tmp.%d.XXXXXXXX", e2lib.globals.tmpdir, - e2util.getpid()) - end - local cmd = string.format("mktemp '%s'", template) - local mktemp = io.popen(cmd, "r") - if not mktemp then - e2lib.abort("can't mktemp") - end - local tmp = mktemp:read() - if not tmp then - e2lib.abort("can't mktemp") - end - mktemp:close() - -- register tmp for removing with rmtempfiles() later on - table.insert(e2lib.globals.tmpfiles, tmp) - e2lib.log(4, string.format("creating temporary file: %s", tmp)) - return tmp + if not template then + template = string.format("%s/e2tmp.%d.XXXXXXXX", e2lib.globals.tmpdir, + e2util.getpid()) + end + local cmd = string.format("mktemp '%s'", template) + local mktemp = io.popen(cmd, "r") + if not mktemp then + e2lib.abort("can't mktemp") + end + local tmp = mktemp:read() + if not tmp then + e2lib.abort("can't mktemp") + end + mktemp:close() + -- register tmp for removing with rmtempfiles() later on + table.insert(e2lib.globals.tmpfiles, tmp) + e2lib.log(4, string.format("creating temporary file: %s", tmp)) + return tmp end --- remove a temporary file and remove it from the builtin list of @@ -1384,13 +1383,13 @@ end -- This function always succeeds (or aborts immediately) -- @param path function e2lib.rmtempfile(tmpfile) - for i,v in ipairs(e2lib.globals.tmpfiles) do - if v == tmpfile then - table.remove(e2lib.globals.tmpfiles, i) - e2lib.log(4, string.format("removing temporary file: %s", tmpfile)) - e2lib.rm(tmpfile, "-f") + for i,v in ipairs(e2lib.globals.tmpfiles) do + if v == tmpfile then + table.remove(e2lib.globals.tmpfiles, i) + e2lib.log(4, string.format("removing temporary file: %s", tmpfile)) + e2lib.rm(tmpfile, "-f") + end end - end end --- Create a temporary directory. @@ -1400,24 +1399,24 @@ end -- @param template string: template name (optional) -- @return string: name of the directory function e2lib.mktempdir(template) - if not template then - template = string.format("%s/e2tmp.%d.XXXXXXXX", e2lib.globals.tmpdir, - e2util.getpid()) - end - local cmd = string.format("mktemp -d '%s'", template) - local mktemp = io.popen(cmd, "r") - if not mktemp then - e2lib.abort("can't mktemp") - end - local tmpdir = mktemp:read() - if not tmpdir then - e2lib.abort("can't mktemp") - end - mktemp:close() - -- register tmpdir for removing with rmtempdirs() later on - table.insert(e2lib.globals.tmpdirs, tmpdir) - e2lib.log(4, string.format("creating temporary directory: %s", tmpdir)) - return tmpdir + if not template then + template = string.format("%s/e2tmp.%d.XXXXXXXX", e2lib.globals.tmpdir, + e2util.getpid()) + end + local cmd = string.format("mktemp -d '%s'", template) + local mktemp = io.popen(cmd, "r") + if not mktemp then + e2lib.abort("can't mktemp") + end + local tmpdir = mktemp:read() + if not tmpdir then + e2lib.abort("can't mktemp") + end + mktemp:close() + -- register tmpdir for removing with rmtempdirs() later on + table.insert(e2lib.globals.tmpdirs, tmpdir) + e2lib.log(4, string.format("creating temporary directory: %s", tmpdir)) + return tmpdir end -- remove a temporary directory and remove it from the builtin list of @@ -1425,32 +1424,32 @@ end -- This function always succeeds (or aborts immediately) -- @param path function e2lib.rmtempdir(tmpdir) - for i,v in ipairs(e2lib.globals.tmpdirs) do - if v == tmpdir then - table.remove(e2lib.globals.tmpdirs, i) - e2lib.log(4, string.format("removing temporary directory: %s", tmpdir)) - e2lib.rm(tmpdir, "-fr") + for i,v in ipairs(e2lib.globals.tmpdirs) do + if v == tmpdir then + table.remove(e2lib.globals.tmpdirs, i) + e2lib.log(4, string.format("removing temporary directory: %s", tmpdir)) + e2lib.rm(tmpdir, "-fr") + end end - end end --- remove temporary directories registered with mktempdir() -- This function does not support error checking and is intended to be -- called from the finish() function. function e2lib.rmtempdirs() - e2lib.chdir("/") -- avoid being inside a temporary directory - while #e2lib.globals.tmpdirs > 0 do - e2lib.rmtempdir(e2lib.globals.tmpdirs[1]) - end + e2lib.chdir("/") -- avoid being inside a temporary directory + while #e2lib.globals.tmpdirs > 0 do + e2lib.rmtempdir(e2lib.globals.tmpdirs[1]) + end end --- remove temporary files registered with mktempfile() -- This function does not support error checking and is intended to be -- called from the finish() function. function e2lib.rmtempfiles() - while #e2lib.globals.tmpfiles > 0 do - e2lib.rmtempfile(e2lib.globals.tmpfiles[1]) - end + while #e2lib.globals.tmpfiles > 0 do + e2lib.rmtempfile(e2lib.globals.tmpfiles[1]) + end end --- call the rm tool with flags and filename @@ -1459,11 +1458,11 @@ end -- @return bool -- @return an error object on failure function e2lib.rm(file, flags) - if not flags then - flags = "" - end - local args = string.format("%s %s", flags, file) - return e2lib.call_tool("rm", args) + if not flags then + flags = "" + end + local args = string.format("%s %s", flags, file) + return e2lib.call_tool("rm", args) end --- call the touch tool with flags and filename @@ -1471,11 +1470,11 @@ end -- @param flags string: flags to pass to touch (optional) -- @returns bool function e2lib.touch(file, flags) - if not flags then - flags = "" - end - local args = string.format("%s %s", flags, file) - return e2lib.call_tool("touch", args) + if not flags then + flags = "" + end + local args = string.format("%s %s", flags, file) + return e2lib.call_tool("touch", args) end --- call the rmdir command @@ -1484,11 +1483,11 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.rmdir(dir, flags) - if not flags then - flags = "" - end - local args = string.format("%s %s", flags, dir) - return e2lib.call_tool("rmdir", args) + if not flags then + flags = "" + end + local args = string.format("%s %s", flags, dir) + return e2lib.call_tool("rmdir", args) end --- call the mkdir command @@ -1497,14 +1496,14 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.mkdir(dir, flags) - flags = flags or "" - assert(type(dir) == "string") - assert(string.len(dir) > 0) - assert(type(flags) == "string") + flags = flags or "" + assert(type(dir) == "string") + assert(string.len(dir) > 0) + assert(type(flags) == "string") - -- TODO: quote flags as well - local args = string.format("%s %s", flags, e2lib.shquote(dir)) - return e2lib.call_tool("mkdir", args) + -- TODO: quote flags as well + local args = string.format("%s %s", flags, e2lib.shquote(dir)) + return e2lib.call_tool("mkdir", args) end --- call the patch command @@ -1513,7 +1512,7 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.patch(args) - return e2lib.call_tool("patch", args) + return e2lib.call_tool("patch", args) end --- call a tool @@ -1522,20 +1521,20 @@ end -- @return bool -- @return string: the last line ouf captured output function e2lib.call_tool(tool, args) - local cmd = tools.get_tool(tool) - if not cmd then - bomb("trying to call invalid tool: " .. tostring(tool)) - end - local flags = tools.get_tool_flags(tool) - if not flags then - bomb("invalid tool flags for tool: " .. tostring(tool)) - end - local call = string.format("%s %s %s", cmd, flags, args) - local rc, e = e2lib.callcmd_log(call) - if rc ~= 0 then - return false, e - end - return true, e + local cmd = tools.get_tool(tool) + if not cmd then + bomb("trying to call invalid tool: " .. tostring(tool)) + end + local flags = tools.get_tool_flags(tool) + if not flags then + bomb("invalid tool flags for tool: " .. tostring(tool)) + end + local call = string.format("%s %s %s", cmd, flags, args) + local rc, e = e2lib.callcmd_log(call) + if rc ~= 0 then + return false, e + end + return true, e end --- call a tool with argv @@ -1544,28 +1543,28 @@ end -- @return bool -- @return string: the last line ouf captured output function e2lib.call_tool_argv(tool, argv) - local cmd = tools.get_tool(tool) - if not cmd then - bomb("trying to call invalid tool: " .. tostring(tool)) - end - local flags = tools.get_tool_flags(tool) - if not flags then - bomb("invalid tool flags for tool: " .. tostring(tool)) - end - - -- TODO: flags should be quoted as well, requires config changes - local call = string.format("%s %s", e2lib.shquote(cmd), flags) - - for _,arg in ipairs(argv) do - assert(type(arg) == "string") - call = call .. " " .. e2lib.shquote(arg) - end + local cmd = tools.get_tool(tool) + if not cmd then + bomb("trying to call invalid tool: " .. tostring(tool)) + end + local flags = tools.get_tool_flags(tool) + if not flags then + bomb("invalid tool flags for tool: " .. tostring(tool)) + end - local rc, e = e2lib.callcmd_log(call) - if rc ~= 0 then - return false, e - end - return true, e + -- TODO: flags should be quoted as well, requires config changes + local call = string.format("%s %s", e2lib.shquote(cmd), flags) + + for _,arg in ipairs(argv) do + assert(type(arg) == "string") + call = call .. " " .. e2lib.shquote(arg) + end + + local rc, e = e2lib.callcmd_log(call) + if rc ~= 0 then + return false, e + end + return true, e end --- call git @@ -1575,36 +1574,36 @@ end -- @return bool -- @return an error object on failure function e2lib.git(gitdir, subtool, args) - local rc, re - local e = err.new("calling git failed") - if not gitdir then - gitdir = ".git" - end - if not args then - args = "" - end - local git, re = tools.get_tool("git") - if not git then - return false, e:cat(re) - end - -- TODO: args should be quoted as well - local call = string.format("GIT_DIR=%s %s %s %s", - e2lib.shquote(gitdir), e2lib.shquote(git), e2lib.shquote(subtool), args) - rc, re = e2lib.callcmd_log(call) - if rc ~= 0 then - e:append(call) - return false, e:cat(re) - end - return true, e + local rc, re + local e = err.new("calling git failed") + if not gitdir then + gitdir = ".git" + end + if not args then + args = "" + end + local git, re = tools.get_tool("git") + if not git then + return false, e:cat(re) + end + -- TODO: args should be quoted as well + local call = string.format("GIT_DIR=%s %s %s %s", + e2lib.shquote(gitdir), e2lib.shquote(git), e2lib.shquote(subtool), args) + rc, re = e2lib.callcmd_log(call) + if rc ~= 0 then + e:append(call) + return false, e:cat(re) + end + return true, e end --- call the svn command -- @param argv table: vector with arguments for svn -- @return bool function e2lib.svn(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("svn", argv) + return e2lib.call_tool_argv("svn", argv) end --- call the ln command @@ -1613,8 +1612,8 @@ end -- @return bool -- @return the last line of captured output function e2lib.symlink(dst, link) - local args = string.format("-s '%s' '%s'", dst, link) - return e2lib.call_tool("ln", args) + local args = string.format("-s '%s' '%s'", dst, link) + return e2lib.call_tool("ln", args) end --- call the chmod command @@ -1623,8 +1622,8 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.chmod(mode, path) - local args = string.format("'%s' '%s'", mode, path) - return e2lib.call_tool("chmod", args) + local args = string.format("'%s' '%s'", mode, path) + return e2lib.call_tool("chmod", args) end --- call the mv command @@ -1633,8 +1632,8 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.mv(src, dst) - local args = string.format("'%s' '%s'", src, dst) - return e2lib.call_tool("mv", args) + local args = string.format("'%s' '%s'", src, dst) + return e2lib.call_tool("mv", args) end --- call the cp command @@ -1644,11 +1643,11 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.cp(src, dst, flags) - if not flags then - flags = "" - end - local args = string.format("%s '%s' '%s'", flags, src, dst) - return e2lib.call_tool("cp", args) + if not flags then + flags = "" + end + local args = string.format("%s '%s' '%s'", flags, src, dst) + return e2lib.call_tool("cp", args) end --- call the ln command @@ -1658,11 +1657,11 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.ln(src, dst, flags) - if not flags then - flags = "" - end - local args = string.format("%s '%s' '%s'", flags, src, dst) - return e2lib.call_tool("ln", args) + if not flags then + flags = "" + end + local args = string.format("%s '%s' '%s'", flags, src, dst) + return e2lib.call_tool("ln", args) end --- call the curl command @@ -1670,9 +1669,9 @@ end -- @return bool -- @return an error object on failure function e2lib.curl(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("curl", argv) + return e2lib.call_tool_argv("curl", argv) end --- call the ssh command @@ -1680,9 +1679,9 @@ end -- @return bool -- @return an error object on failure function e2lib.ssh(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("ssh", argv) + return e2lib.call_tool_argv("ssh", argv) end --- call the scp command @@ -1690,9 +1689,9 @@ end -- @return bool -- @return an error object on failure function e2lib.scp(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("scp", argv) + return e2lib.call_tool_argv("scp", argv) end --- call the rsync command @@ -1700,9 +1699,9 @@ end -- @return bool -- @return an error object on failure function e2lib.rsync(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("rsync", argv) + return e2lib.call_tool_argv("rsync", argv) end --- call the gzip command @@ -1710,9 +1709,9 @@ end -- @return bool -- @return the last line ouf captured output function e2lib.gzip(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("gzip", argv) + return e2lib.call_tool_argv("gzip", argv) end --- call the catcommand @@ -1720,28 +1719,28 @@ end -- @return bool -- @return an error object on failure function e2lib.cat(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("cat", argv) + return e2lib.call_tool_argv("cat", argv) end --- check if dir is a directory -- @param dir string: path -- @return bool function e2lib.isdir(dir) - local args = string.format("-d '%s'", dir) - return e2lib.call_tool("test", args) + local args = string.format("-d '%s'", dir) + return e2lib.call_tool("test", args) end --- check if path is a file -- @param dir string: path -- @return bool function e2lib.isfile(path) - local t = e2util.stat(path, true) - if not t or t.type ~= "regular" then - return false - end - return true + local t = e2util.stat(path, true) + if not t or t.type ~= "regular" then + return false + end + return true end --- calculate SHA1 sum for a file @@ -1749,111 +1748,111 @@ end -- @return string: sha1 sum of file -- @return an error object on failure function e2lib.sha1sum(path) - assert(type(path) == "string") + assert(type(path) == "string") - local e = err.new("calculating SHA1 checksum failed") + local e = err.new("calculating SHA1 checksum failed") - local sha1sum, re = tools.get_tool("sha1sum") - if not sha1sum then - return nil, e:cat(re) - end + local sha1sum, re = tools.get_tool("sha1sum") + if not sha1sum then + return nil, e:cat(re) + end - local sha1sum_flags, re = tools.get_tool_flags("sha1sum") - if not sha1sum_flags then - return nil, e:cat(re) - end + local sha1sum_flags, re = tools.get_tool_flags("sha1sum") + if not sha1sum_flags then + return nil, e:cat(re) + end - -- TODO: sha1sum_flags should be quoted as well - local cmd = string.format("%s %s %s", e2lib.shquote(sha1sum), sha1sum_flags, + -- TODO: sha1sum_flags should be quoted as well + local cmd = string.format("%s %s %s", e2lib.shquote(sha1sum), sha1sum_flags, e2lib.shquote(path)) - local p, msg = io.popen(cmd, "r") - if not p then - return nil, e:cat(msg) - end + local p, msg = io.popen(cmd, "r") + if not p then + return nil, e:cat(msg) + end - local out, msg = p:read("*l") - p:close() + local out, msg = p:read("*l") + p:close() - local sha1, file = out:match("(%S+) (%S+)") - if type(sha1) ~= "string" then - return nil, e:cat("parsing sha1sum output failed") - end - return sha1 + local sha1, file = out:match("(%S+) (%S+)") + if type(sha1) ~= "string" then + return nil, e:cat("parsing sha1sum output failed") + end + return sha1 end --- call the e2-su command -- @param argv table: argument vector -- @return bool function e2lib.e2_su(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("e2-su", argv) + return e2lib.call_tool_argv("e2-su", argv) end --- call the e2-su-2.2 command -- @param argv table: argument vector -- @return bool function e2lib.e2_su_2_2(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("e2-su-2.2", argv) + return e2lib.call_tool_argv("e2-su-2.2", argv) end --- call the tar command -- @param argv table: argument vector -- @return bool function e2lib.tar(argv) - assert(type(argv) == "table") + assert(type(argv) == "table") - return e2lib.call_tool_argv("tar", argv) + return e2lib.call_tool_argv("tar", argv) end --- get system architecture -- @return string: machine hardware name -- @return an error object on failure function e2lib.get_sys_arch() - local rc, re - local e = err.new("getting host system architecture failed") - local uname = tools.get_tool("uname") - local cmd = string.format("%s -m", e2lib.shquote(uname)) - local p, msg = io.popen(cmd, "r") - if not p then - return nil, e:cat(msg) - end - local l, msg = p:read() - if not l then - return nil, e:cat(msg) - end - local arch = l:match("(%S+)") - if not arch then - return nil, e:append("%s: %s: cannot parse", cmd, l) - end - return arch, nil + local rc, re + local e = err.new("getting host system architecture failed") + local uname = tools.get_tool("uname") + local cmd = string.format("%s -m", e2lib.shquote(uname)) + local p, msg = io.popen(cmd, "r") + if not p then + return nil, e:cat(msg) + end + local l, msg = p:read() + if not l then + return nil, e:cat(msg) + end + local arch = l:match("(%S+)") + if not arch then + return nil, e:append("%s: %s: cannot parse", cmd, l) + end + return arch, nil end --- return a table of parent directories -- @param path string: path -- @return a table of parent directories, including path. function e2lib.parentdirs(path) - local i = 2 - local t = {} - local stop = false - while true do - local px - local p = path:find("/", i) - if not p then - p = #path - stop = true - end - px = path:sub(1, p) - table.insert(t, px) - i = p + 1 - if stop then - break - end - end - return t + local i = 2 + local t = {} + local stop = false + while true do + local px + local p = path:find("/", i) + if not p then + p = #path + stop = true + end + px = path:sub(1, p) + table.insert(t, px) + i = p + 1 + if stop then + break + end + end + return t end --- write a string to a file @@ -1862,17 +1861,17 @@ end -- @return bool -- @return nil, or an error string function e2lib.write_file(file, data) - local f, msg = io.open(file, "w") - if not f then - return false, string.format("open failed: %s", msg) - end - local rc, msg = f:write(data) - if not rc then + local f, msg = io.open(file, "w") + if not f then + return false, string.format("open failed: %s", msg) + end + local rc, msg = f:write(data) + if not rc then + f:close() + return false, string.format("write failed: %s", msg) + end f:close() - return false, string.format("write failed: %s", msg) - end - f:close() - return true, nil + return true, nil end --- read a file into a string @@ -1880,16 +1879,16 @@ end -- @return string: the file content -- @return nil, or an error object function e2lib.read_file(file) - local f, msg = io.open(file, "r") - if not f then - return nil, err.new("%s", msg) - end - local s, msg = f:read("*a") - if not s then - return nil, err.new("%s", msg) - end - f:close() - return s, nil + local f, msg = io.open(file, "r") + if not f then + return nil, err.new("%s", msg) + end + local s, msg = f:read("*a") + if not s then + return nil, err.new("%s", msg) + end + f:close() + return s, nil end --- read a template file, located relative to the current template directory @@ -1897,13 +1896,13 @@ end -- @return string: the file content -- @return an error object on failure function e2lib.read_template(file) - local e = err.new("error reading template file") - local filename = string.format("%s/%s", e2lib.globals.template_path, file) - local template, re = e2lib.read_file(filename) - if not template then - return nil, e:cat(re) - end - return template, nil + local e = err.new("error reading template file") + local filename = string.format("%s/%s", e2lib.globals.template_path, file) + local template, re = e2lib.read_file(filename) + if not template then + return nil, e:cat(re) + end + return template, nil end --- parse a server:location string, taking a default server into account @@ -1912,51 +1911,51 @@ end -- @return a table with fields server and location, nil on error -- @return nil, an error string on error function e2lib.parse_server_location(arg, default_server) - local sl = {} - sl.server, sl.location = arg:match("(%S+):(%S+)") - if not (sl.server and sl.location) then - sl.location = arg:match("(%S+)") - if not (sl.location and default_server) then - return nil, "can't parse location" - end - sl.server = default_server - end - if sl.location:match("[.][.]") or - sl.location:match("^/") then - return nil, "invalid location" - end - return sl + local sl = {} + sl.server, sl.location = arg:match("(%S+):(%S+)") + if not (sl.server and sl.location) then + sl.location = arg:match("(%S+)") + if not (sl.location and default_server) then + return nil, "can't parse location" + end + sl.server = default_server + end + if sl.location:match("[.][.]") or + sl.location:match("^/") then + return nil, "invalid location" + end + return sl end --- setup cache from the global server configuration -- @return a cache object -- @return an error object on failure function e2lib.setup_cache() - local e = err.new("setting up cache failed") - local config = e2lib.get_global_config() - if type(config.cache) ~= "table" or type(config.cache.path) ~= "string" then - return false, e:append("invalid cache configuration: config.cache.path") - end - local replace = { u=e2lib.globals.username } - local cache_path = e2lib.format_replace(config.cache.path, replace) - local cache_url = string.format("file://%s", cache_path) - local c, re = cache.new_cache("local cache", cache_url) - if not c then - return nil, e:cat(re) - end - for name,server in pairs(config.servers) do - local flags = {} - flags.cachable = server.cachable - flags.cache = server.cache - flags.islocal = server.islocal - flags.writeback = server.writeback - flags.push_permissions = server.push_permissions - local rc, re = cache.new_cache_entry(c, name, server.url, flags) - if not rc then - return nil, e:cat(re) + local e = err.new("setting up cache failed") + local config = e2lib.get_global_config() + if type(config.cache) ~= "table" or type(config.cache.path) ~= "string" then + return false, e:append("invalid cache configuration: config.cache.path") end - end - return c, nil + local replace = { u=e2lib.globals.username } + local cache_path = e2lib.format_replace(config.cache.path, replace) + local cache_url = string.format("file://%s", cache_path) + local c, re = cache.new_cache("local cache", cache_url) + if not c then + return nil, e:cat(re) + end + for name,server in pairs(config.servers) do + local flags = {} + flags.cachable = server.cachable + flags.cache = server.cache + flags.islocal = server.islocal + flags.writeback = server.writeback + flags.push_permissions = server.push_permissions + local rc, re = cache.new_cache_entry(c, name, server.url, flags) + if not rc then + return nil, e:cat(re) + end + end + return c, nil end --- replace format elements, according to the table @@ -1964,37 +1963,37 @@ end -- @param t table: a table of key-value pairs -- @return string function e2lib.format_replace(s, t) - -- t has the format { f="foo" } to replace %f by foo inside the string - -- %% is automatically replaced by % - local start = 1 - while true do - local p = s:find("%%", start) - if not p then - break - end - t["%"] = "%" - for x,y in pairs(t) do - if s:sub(p+1, p+1) == x then - s = s:sub(1, p-1) .. y .. s:sub(p+2, #s) - start = p + #y - break - end - end - start = start + 1 - end - return s + -- t has the format { f="foo" } to replace %f by foo inside the string + -- %% is automatically replaced by % + local start = 1 + while true do + local p = s:find("%%", start) + if not p then + break + end + t["%"] = "%" + for x,y in pairs(t) do + if s:sub(p+1, p+1) == x then + s = s:sub(1, p-1) .. y .. s:sub(p+2, #s) + start = p + #y + break + end + end + start = start + 1 + end + return s end --- take a table of values, with integer keys and return the first string -- value -- @param a table of values function e2lib.get_first_val(t) - for k, v in pairs(t) do - if type(v) == "string" then - return v + for k, v in pairs(t) do + if type(v) == "string" then + return v + end end - end - return nil + return nil end --- change directory @@ -2002,12 +2001,12 @@ end -- @return bool -- @return an error object on failure function e2lib.chdir(path) - local rc, re - rc, re = e2util.cd(path) - if not rc then - return false, err.new("chdir %s failed: %s", path, re) - end - return true, nil + local rc, re + rc, re = e2util.cd(path) + if not rc then + return false, err.new("chdir %s failed: %s", path, re) + end + return true, nil end --- align strings @@ -2017,24 +2016,26 @@ end -- @param align2 column to align string2 to -- @param string2 second string function e2lib.align(columns, align1, string1, align2, string2) - local lines = 1 - if align2 + #string2 > columns then - -- try to move string2 to the left first - align2 = columns - #string2 - end - if align1 + #string1 + #string2 > columns then - -- split into two lines - lines = 2 - end - local s - if lines == 1 then - s = string.rep(" ", align1) .. string1 .. - string.rep(" ", align2 - #string1 - align1) .. string2 - else - s = string.rep(" ", align1) .. string1 .. "\n" .. - string.rep(" ", align2) .. string2 - end - return s + local lines = 1 + if align2 + #string2 > columns then + -- try to move string2 to the left first + align2 = columns - #string2 + end + if align1 + #string1 + #string2 > columns then + -- split into two lines + lines = 2 + end + local s + if lines == 1 then + s = string.rep(" ", align1) .. string1 .. + string.rep(" ", align2 - #string1 - align1) .. string2 + else + s = string.rep(" ", align1) .. string1 .. "\n" .. + string.rep(" ", align2) .. string2 + end + return s end return e2lib + +-- vim:sw=4:sts=4:et: -- 2.39.5