1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/openpkg/rpmlua Tue Jul 31 12:23:42 2012 +0200 1.3 @@ -0,0 +1,228 @@ 1.4 +-- 1.5 +-- rpmlua -- OpenPKG RPM Lua Script 1.6 +-- Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/> 1.7 +-- 1.8 +-- This software is property of the OpenPKG GmbH, DE MUC HRB 160208. 1.9 +-- All rights reserved. Licenses which grant limited permission to use, 1.10 +-- copy, modify and distribute this software are available from the 1.11 +-- OpenPKG GmbH. 1.12 +-- 1.13 +-- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 1.14 +-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1.15 +-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.16 +-- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR 1.17 +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.18 +-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.19 +-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 1.20 +-- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1.21 +-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 1.22 +-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 1.23 +-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.24 +-- SUCH DAMAGE. 1.25 +-- 1.26 + 1.27 +-- 1.28 +-- The purpose of this Lua script is to extend the default Lua functions 1.29 +-- in the OpenPKG RPM installation for the @l_prefix@ hierarchy. 1.30 +-- 1.31 + 1.32 +-- provide namespace 1.33 +openpkg = {} 1.34 + 1.35 +-- small wrapper around the realpath(3) call provided by RPM 1.36 +function openpkg.realpath(path) 1.37 + if posix.stat(path) ~= nil then 1.38 + -- path exists, so resolve as a whole 1.39 + path = rpm.realpath(path) 1.40 + else 1.41 + -- path not exists, so recursively resolve only prefix 1.42 + local s, _, m = util.rmatch(path, "^(.+?)/([^/]+)/?$") 1.43 + if s ~= nil then 1.44 + local prefix = openpkg.realpath(m[1]) 1.45 + if util.rmatch(prefix, "/$") == nil then 1.46 + prefix = prefix .. "/" 1.47 + end 1.48 + path = prefix .. m[2] 1.49 + end 1.50 + end 1.51 + return path 1.52 +end 1.53 + 1.54 +-- try to reduce real path to symbolic one (if posssible) 1.55 +function openpkg.unrealpath(path, prefix_unreal) 1.56 + local prefix_real = openpkg.realpath(prefix_unreal) 1.57 + if prefix_real ~= prefix_unreal then 1.58 + if string.sub(path, 1, string.len(prefix_real)) == prefix_real then 1.59 + path = prefix_unreal .. string.sub(path, string.len(prefix_real)+1) 1.60 + end 1.61 + end 1.62 + return path 1.63 +end 1.64 + 1.65 +-- canonicalize filesystem path as good as possible 1.66 +function openpkg.canonicalize(path) 1.67 + path = openpkg.unrealpath(path, os.getenv("PWD")) 1.68 + path = openpkg.unrealpath(path, rpm.expand("%{l_prefix}")) 1.69 + return path 1.70 +end 1.71 + 1.72 +-- temporary directory determination 1.73 +function openpkg.tmpdir() 1.74 + local tmpdir = os.getenv("TMPDIR") 1.75 + if tmpdir ~= nil then 1.76 + tmpdir = openpkg.canonicalize(openpkg.realpath(tmpdir)) 1.77 + else 1.78 + tmpdir = "/tmp" 1.79 + end 1.80 + tmpdir = tmpdir .. "/openpkg" 1.81 + return tmpdir 1.82 +end 1.83 + 1.84 +-- layout determination: RPM Lua based implementation 1.85 +function openpkg.layout(args) 1.86 + local dir = "" 1.87 + 1.88 + -- parse arguments 1.89 + local arg = { 1.90 + variable = "", 1.91 + layout = "", 1.92 + macrosfile = "", 1.93 + basedir = "", 1.94 + shared = "no", 1.95 + debug = "no", 1.96 + specdir = "", 1.97 + sourcedir = "", 1.98 + builddir = "", 1.99 + tmppath = "", 1.100 + rpmdir = "", 1.101 + srcrpmdir = "" 1.102 + } 1.103 + local arg_map_fwd = { 1.104 + binrpmdir = "rpmdir", 1.105 + tmpdir = "tmppath" 1.106 + } 1.107 + local arg_map_rev = { 1.108 + rpmdir = "binrpmdir", 1.109 + tmppath = "tmpdir" 1.110 + } 1.111 + if rpm.debug() then 1.112 + arg.debug = "yes" 1.113 + end 1.114 + util.rsubst(args, "(?s)\\s*([a-z_][a-zA-Z0-9_-]*)=(?:\"((?:\\\\.|[^\"])*)\"|(\\S*))", 1.115 + function (key, _, value1, value2) 1.116 + if arg_map_fwd[key] ~= nil then 1.117 + key = arg_map_fwd[key] 1.118 + end 1.119 + if arg[key] == nil then 1.120 + io.stderr:write("rpm: invalid parameter \"" .. key .. "\" on call to \"openpkg.layout()\"\n") 1.121 + else 1.122 + if value1 ~= nil then arg[key] = value1 else arg[key] = value2 end 1.123 + end 1.124 + return false 1.125 + end 1.126 + ) 1.127 + if arg.variable == "" then 1.128 + io.stderr:write("rpm: missing \"variable\" parameter on call to \"openpkg.layout()\"\n") 1.129 + return "" 1.130 + end 1.131 + if arg.layout == "" then 1.132 + io.stderr:write("rpm: missing \"layout\" parameter on call to \"openpkg.layout()\"\n") 1.133 + return "" 1.134 + end 1.135 + if arg.macrosfile == "" and arg.basedir == "" then 1.136 + io.stderr:write("rpm: missing \"macrosfile\" or \"basedir\" parameter on call to \"openpkg.layout()\"\n") 1.137 + return "" 1.138 + end 1.139 + 1.140 + -- determine base directory 1.141 + if arg.basedir == "" then 1.142 + if util.rmatch(arg.macrosfile, "^.*/\.openpkg/rpmmacros$") ~= nil then 1.143 + arg.basedir = openpkg.canonicalize(openpkg.realpath( 1.144 + util.rsubst( 1.145 + openpkg.realpath(arg.macrosfile), 1.146 + "/[^/]+$", "/.." 1.147 + ) 1.148 + )) 1.149 + else 1.150 + arg.basedir = rpm.expand("%{l_prefix}") 1.151 + end 1.152 + end 1.153 + 1.154 + -- temporarily define "__openpkg_basedir" macro 1.155 + rpm.define("__openpkg_basedir " .. arg.basedir) 1.156 + 1.157 + -- temporarily define "__openpkg_shared" macro 1.158 + if arg.shared == "yes" then 1.159 + rpm.define("__openpkg_shared yes") 1.160 + end 1.161 + 1.162 + -- determine layout directory list 1.163 + local list = "" 1.164 + if arg[arg.variable] ~= nil and arg[arg.variable] ~= "" then 1.165 + list = arg[arg.variable] 1.166 + else 1.167 + list = rpm.expand( 1.168 + "%{?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. "}" .. 1.169 + "%{!?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. ":" .. 1.170 + "%{__openpkg_layout_global_" .. arg.variable .. "}}" 1.171 + ) 1.172 + end 1.173 + 1.174 + -- remove temporarily defined "__openpkg_basedir" macro 1.175 + rpm.undefine("__openpkg_basedir") 1.176 + 1.177 + -- remove temporarily defined "__openpkg_shared" macro 1.178 + if arg.shared == "yes" then 1.179 + rpm.undefine("__openpkg_shared") 1.180 + end 1.181 + 1.182 + -- iterate over all directory specifications 1.183 + local dirs = util.rsplit(list, "(?s)\\s+") 1.184 + local k = table.maxn(dirs) 1.185 + for i, _ in ipairs(dirs) do 1.186 + -- parse specification into path to check and optionally path to make 1.187 + local path_check = dirs[i] 1.188 + local path_append = false 1.189 + local path_make = path_check 1.190 + local s, _, m = util.rmatch(path_check, "^(.+):(\\+?)(.*)$") 1.191 + if s ~= nil then 1.192 + path_check = m[1] 1.193 + path_append = (m[2] == "+") 1.194 + path_make = m[3] 1.195 + end 1.196 + -- check whether path should be taken (last path is always taken) 1.197 + if posix.stat(path_check) ~= nil or i == k then 1.198 + if path_append then 1.199 + -- special case: simply append a suffix 1.200 + dir = path_check .. path_make 1.201 + else 1.202 + -- regular case: use full path to make 1.203 + dir = path_make 1.204 + end 1.205 + break 1.206 + end 1.207 + end 1.208 + if dir ~= "" then 1.209 + -- make sure path really exists and resolve to absolute path 1.210 + if posix.stat(dir) == nil then 1.211 + io.stderr:write("rpm: creating \"" .. arg.variable .. "\" directory \"" .. dir .. "\"\n") 1.212 + if posix.mkdir(dir) ~= 0 then 1.213 + io.stderr:write("rpm: failed to create directory \"" .. dir .. "\"\n") 1.214 + end 1.215 + end 1.216 + dir = openpkg.canonicalize(openpkg.realpath(dir)) 1.217 + end 1.218 + 1.219 + -- debugging 1.220 + if arg.debug == "yes" then 1.221 + local variable = arg.variable 1.222 + if arg_map_rev[variable] ~= nil then 1.223 + variable = arg_map_rev[variable] 1.224 + end 1.225 + io.stderr:write(string.format("rpm: openpkg: layout: [%s] %s = \"%s\"\n", arg.layout, variable, dir)) 1.226 + end 1.227 + 1.228 + -- provide result directory 1.229 + return dir 1.230 +end 1.231 +