diff -r 71503088f51b -r f880f219c566 openpkg/rpmlua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/openpkg/rpmlua Tue Jul 31 12:23:42 2012 +0200 @@ -0,0 +1,228 @@ +-- +-- rpmlua -- OpenPKG RPM Lua Script +-- Copyright (c) 2000-2012 OpenPKG GmbH +-- +-- This software is property of the OpenPKG GmbH, DE MUC HRB 160208. +-- All rights reserved. Licenses which grant limited permission to use, +-- copy, modify and distribute this software are available from the +-- OpenPKG GmbH. +-- +-- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +-- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +-- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-- SUCH DAMAGE. +-- + +-- +-- The purpose of this Lua script is to extend the default Lua functions +-- in the OpenPKG RPM installation for the @l_prefix@ hierarchy. +-- + +-- provide namespace +openpkg = {} + +-- small wrapper around the realpath(3) call provided by RPM +function openpkg.realpath(path) + if posix.stat(path) ~= nil then + -- path exists, so resolve as a whole + path = rpm.realpath(path) + else + -- path not exists, so recursively resolve only prefix + local s, _, m = util.rmatch(path, "^(.+?)/([^/]+)/?$") + if s ~= nil then + local prefix = openpkg.realpath(m[1]) + if util.rmatch(prefix, "/$") == nil then + prefix = prefix .. "/" + end + path = prefix .. m[2] + end + end + return path +end + +-- try to reduce real path to symbolic one (if posssible) +function openpkg.unrealpath(path, prefix_unreal) + local prefix_real = openpkg.realpath(prefix_unreal) + if prefix_real ~= prefix_unreal then + if string.sub(path, 1, string.len(prefix_real)) == prefix_real then + path = prefix_unreal .. string.sub(path, string.len(prefix_real)+1) + end + end + return path +end + +-- canonicalize filesystem path as good as possible +function openpkg.canonicalize(path) + path = openpkg.unrealpath(path, os.getenv("PWD")) + path = openpkg.unrealpath(path, rpm.expand("%{l_prefix}")) + return path +end + +-- temporary directory determination +function openpkg.tmpdir() + local tmpdir = os.getenv("TMPDIR") + if tmpdir ~= nil then + tmpdir = openpkg.canonicalize(openpkg.realpath(tmpdir)) + else + tmpdir = "/tmp" + end + tmpdir = tmpdir .. "/openpkg" + return tmpdir +end + +-- layout determination: RPM Lua based implementation +function openpkg.layout(args) + local dir = "" + + -- parse arguments + local arg = { + variable = "", + layout = "", + macrosfile = "", + basedir = "", + shared = "no", + debug = "no", + specdir = "", + sourcedir = "", + builddir = "", + tmppath = "", + rpmdir = "", + srcrpmdir = "" + } + local arg_map_fwd = { + binrpmdir = "rpmdir", + tmpdir = "tmppath" + } + local arg_map_rev = { + rpmdir = "binrpmdir", + tmppath = "tmpdir" + } + if rpm.debug() then + arg.debug = "yes" + end + util.rsubst(args, "(?s)\\s*([a-z_][a-zA-Z0-9_-]*)=(?:\"((?:\\\\.|[^\"])*)\"|(\\S*))", + function (key, _, value1, value2) + if arg_map_fwd[key] ~= nil then + key = arg_map_fwd[key] + end + if arg[key] == nil then + io.stderr:write("rpm: invalid parameter \"" .. key .. "\" on call to \"openpkg.layout()\"\n") + else + if value1 ~= nil then arg[key] = value1 else arg[key] = value2 end + end + return false + end + ) + if arg.variable == "" then + io.stderr:write("rpm: missing \"variable\" parameter on call to \"openpkg.layout()\"\n") + return "" + end + if arg.layout == "" then + io.stderr:write("rpm: missing \"layout\" parameter on call to \"openpkg.layout()\"\n") + return "" + end + if arg.macrosfile == "" and arg.basedir == "" then + io.stderr:write("rpm: missing \"macrosfile\" or \"basedir\" parameter on call to \"openpkg.layout()\"\n") + return "" + end + + -- determine base directory + if arg.basedir == "" then + if util.rmatch(arg.macrosfile, "^.*/\.openpkg/rpmmacros$") ~= nil then + arg.basedir = openpkg.canonicalize(openpkg.realpath( + util.rsubst( + openpkg.realpath(arg.macrosfile), + "/[^/]+$", "/.." + ) + )) + else + arg.basedir = rpm.expand("%{l_prefix}") + end + end + + -- temporarily define "__openpkg_basedir" macro + rpm.define("__openpkg_basedir " .. arg.basedir) + + -- temporarily define "__openpkg_shared" macro + if arg.shared == "yes" then + rpm.define("__openpkg_shared yes") + end + + -- determine layout directory list + local list = "" + if arg[arg.variable] ~= nil and arg[arg.variable] ~= "" then + list = arg[arg.variable] + else + list = rpm.expand( + "%{?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. "}" .. + "%{!?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. ":" .. + "%{__openpkg_layout_global_" .. arg.variable .. "}}" + ) + end + + -- remove temporarily defined "__openpkg_basedir" macro + rpm.undefine("__openpkg_basedir") + + -- remove temporarily defined "__openpkg_shared" macro + if arg.shared == "yes" then + rpm.undefine("__openpkg_shared") + end + + -- iterate over all directory specifications + local dirs = util.rsplit(list, "(?s)\\s+") + local k = table.maxn(dirs) + for i, _ in ipairs(dirs) do + -- parse specification into path to check and optionally path to make + local path_check = dirs[i] + local path_append = false + local path_make = path_check + local s, _, m = util.rmatch(path_check, "^(.+):(\\+?)(.*)$") + if s ~= nil then + path_check = m[1] + path_append = (m[2] == "+") + path_make = m[3] + end + -- check whether path should be taken (last path is always taken) + if posix.stat(path_check) ~= nil or i == k then + if path_append then + -- special case: simply append a suffix + dir = path_check .. path_make + else + -- regular case: use full path to make + dir = path_make + end + break + end + end + if dir ~= "" then + -- make sure path really exists and resolve to absolute path + if posix.stat(dir) == nil then + io.stderr:write("rpm: creating \"" .. arg.variable .. "\" directory \"" .. dir .. "\"\n") + if posix.mkdir(dir) ~= 0 then + io.stderr:write("rpm: failed to create directory \"" .. dir .. "\"\n") + end + end + dir = openpkg.canonicalize(openpkg.realpath(dir)) + end + + -- debugging + if arg.debug == "yes" then + local variable = arg.variable + if arg_map_rev[variable] ~= nil then + variable = arg_map_rev[variable] + end + io.stderr:write(string.format("rpm: openpkg: layout: [%s] %s = \"%s\"\n", arg.layout, variable, dir)) + end + + -- provide result directory + return dir +end +