| |
1 -- |
| |
2 -- rpmlua -- OpenPKG RPM Lua Script |
| |
3 -- Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/> |
| |
4 -- |
| |
5 -- This software is property of the OpenPKG GmbH, DE MUC HRB 160208. |
| |
6 -- All rights reserved. Licenses which grant limited permission to use, |
| |
7 -- copy, modify and distribute this software are available from the |
| |
8 -- OpenPKG GmbH. |
| |
9 -- |
| |
10 -- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
| |
11 -- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| |
12 -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| |
13 -- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
| |
14 -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| |
15 -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| |
16 -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| |
17 -- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| |
18 -- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| |
19 -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| |
20 -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| |
21 -- SUCH DAMAGE. |
| |
22 -- |
| |
23 |
| |
24 -- |
| |
25 -- The purpose of this Lua script is to extend the default Lua functions |
| |
26 -- in the OpenPKG RPM installation for the @l_prefix@ hierarchy. |
| |
27 -- |
| |
28 |
| |
29 -- provide namespace |
| |
30 openpkg = {} |
| |
31 |
| |
32 -- small wrapper around the realpath(3) call provided by RPM |
| |
33 function openpkg.realpath(path) |
| |
34 if posix.stat(path) ~= nil then |
| |
35 -- path exists, so resolve as a whole |
| |
36 path = rpm.realpath(path) |
| |
37 else |
| |
38 -- path not exists, so recursively resolve only prefix |
| |
39 local s, _, m = util.rmatch(path, "^(.+?)/([^/]+)/?$") |
| |
40 if s ~= nil then |
| |
41 local prefix = openpkg.realpath(m[1]) |
| |
42 if util.rmatch(prefix, "/$") == nil then |
| |
43 prefix = prefix .. "/" |
| |
44 end |
| |
45 path = prefix .. m[2] |
| |
46 end |
| |
47 end |
| |
48 return path |
| |
49 end |
| |
50 |
| |
51 -- try to reduce real path to symbolic one (if posssible) |
| |
52 function openpkg.unrealpath(path, prefix_unreal) |
| |
53 local prefix_real = openpkg.realpath(prefix_unreal) |
| |
54 if prefix_real ~= prefix_unreal then |
| |
55 if string.sub(path, 1, string.len(prefix_real)) == prefix_real then |
| |
56 path = prefix_unreal .. string.sub(path, string.len(prefix_real)+1) |
| |
57 end |
| |
58 end |
| |
59 return path |
| |
60 end |
| |
61 |
| |
62 -- canonicalize filesystem path as good as possible |
| |
63 function openpkg.canonicalize(path) |
| |
64 path = openpkg.unrealpath(path, os.getenv("PWD")) |
| |
65 path = openpkg.unrealpath(path, rpm.expand("%{l_prefix}")) |
| |
66 return path |
| |
67 end |
| |
68 |
| |
69 -- temporary directory determination |
| |
70 function openpkg.tmpdir() |
| |
71 local tmpdir = os.getenv("TMPDIR") |
| |
72 if tmpdir ~= nil then |
| |
73 tmpdir = openpkg.canonicalize(openpkg.realpath(tmpdir)) |
| |
74 else |
| |
75 tmpdir = "/tmp" |
| |
76 end |
| |
77 tmpdir = tmpdir .. "/openpkg" |
| |
78 return tmpdir |
| |
79 end |
| |
80 |
| |
81 -- layout determination: RPM Lua based implementation |
| |
82 function openpkg.layout(args) |
| |
83 local dir = "" |
| |
84 |
| |
85 -- parse arguments |
| |
86 local arg = { |
| |
87 variable = "", |
| |
88 layout = "", |
| |
89 macrosfile = "", |
| |
90 basedir = "", |
| |
91 shared = "no", |
| |
92 debug = "no", |
| |
93 specdir = "", |
| |
94 sourcedir = "", |
| |
95 builddir = "", |
| |
96 tmppath = "", |
| |
97 rpmdir = "", |
| |
98 srcrpmdir = "" |
| |
99 } |
| |
100 local arg_map_fwd = { |
| |
101 binrpmdir = "rpmdir", |
| |
102 tmpdir = "tmppath" |
| |
103 } |
| |
104 local arg_map_rev = { |
| |
105 rpmdir = "binrpmdir", |
| |
106 tmppath = "tmpdir" |
| |
107 } |
| |
108 if rpm.debug() then |
| |
109 arg.debug = "yes" |
| |
110 end |
| |
111 util.rsubst(args, "(?s)\\s*([a-z_][a-zA-Z0-9_-]*)=(?:\"((?:\\\\.|[^\"])*)\"|(\\S*))", |
| |
112 function (key, _, value1, value2) |
| |
113 if arg_map_fwd[key] ~= nil then |
| |
114 key = arg_map_fwd[key] |
| |
115 end |
| |
116 if arg[key] == nil then |
| |
117 io.stderr:write("rpm: invalid parameter \"" .. key .. "\" on call to \"openpkg.layout()\"\n") |
| |
118 else |
| |
119 if value1 ~= nil then arg[key] = value1 else arg[key] = value2 end |
| |
120 end |
| |
121 return false |
| |
122 end |
| |
123 ) |
| |
124 if arg.variable == "" then |
| |
125 io.stderr:write("rpm: missing \"variable\" parameter on call to \"openpkg.layout()\"\n") |
| |
126 return "" |
| |
127 end |
| |
128 if arg.layout == "" then |
| |
129 io.stderr:write("rpm: missing \"layout\" parameter on call to \"openpkg.layout()\"\n") |
| |
130 return "" |
| |
131 end |
| |
132 if arg.macrosfile == "" and arg.basedir == "" then |
| |
133 io.stderr:write("rpm: missing \"macrosfile\" or \"basedir\" parameter on call to \"openpkg.layout()\"\n") |
| |
134 return "" |
| |
135 end |
| |
136 |
| |
137 -- determine base directory |
| |
138 if arg.basedir == "" then |
| |
139 if util.rmatch(arg.macrosfile, "^.*/\.openpkg/rpmmacros$") ~= nil then |
| |
140 arg.basedir = openpkg.canonicalize(openpkg.realpath( |
| |
141 util.rsubst( |
| |
142 openpkg.realpath(arg.macrosfile), |
| |
143 "/[^/]+$", "/.." |
| |
144 ) |
| |
145 )) |
| |
146 else |
| |
147 arg.basedir = rpm.expand("%{l_prefix}") |
| |
148 end |
| |
149 end |
| |
150 |
| |
151 -- temporarily define "__openpkg_basedir" macro |
| |
152 rpm.define("__openpkg_basedir " .. arg.basedir) |
| |
153 |
| |
154 -- temporarily define "__openpkg_shared" macro |
| |
155 if arg.shared == "yes" then |
| |
156 rpm.define("__openpkg_shared yes") |
| |
157 end |
| |
158 |
| |
159 -- determine layout directory list |
| |
160 local list = "" |
| |
161 if arg[arg.variable] ~= nil and arg[arg.variable] ~= "" then |
| |
162 list = arg[arg.variable] |
| |
163 else |
| |
164 list = rpm.expand( |
| |
165 "%{?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. "}" .. |
| |
166 "%{!?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. ":" .. |
| |
167 "%{__openpkg_layout_global_" .. arg.variable .. "}}" |
| |
168 ) |
| |
169 end |
| |
170 |
| |
171 -- remove temporarily defined "__openpkg_basedir" macro |
| |
172 rpm.undefine("__openpkg_basedir") |
| |
173 |
| |
174 -- remove temporarily defined "__openpkg_shared" macro |
| |
175 if arg.shared == "yes" then |
| |
176 rpm.undefine("__openpkg_shared") |
| |
177 end |
| |
178 |
| |
179 -- iterate over all directory specifications |
| |
180 local dirs = util.rsplit(list, "(?s)\\s+") |
| |
181 local k = table.maxn(dirs) |
| |
182 for i, _ in ipairs(dirs) do |
| |
183 -- parse specification into path to check and optionally path to make |
| |
184 local path_check = dirs[i] |
| |
185 local path_append = false |
| |
186 local path_make = path_check |
| |
187 local s, _, m = util.rmatch(path_check, "^(.+):(\\+?)(.*)$") |
| |
188 if s ~= nil then |
| |
189 path_check = m[1] |
| |
190 path_append = (m[2] == "+") |
| |
191 path_make = m[3] |
| |
192 end |
| |
193 -- check whether path should be taken (last path is always taken) |
| |
194 if posix.stat(path_check) ~= nil or i == k then |
| |
195 if path_append then |
| |
196 -- special case: simply append a suffix |
| |
197 dir = path_check .. path_make |
| |
198 else |
| |
199 -- regular case: use full path to make |
| |
200 dir = path_make |
| |
201 end |
| |
202 break |
| |
203 end |
| |
204 end |
| |
205 if dir ~= "" then |
| |
206 -- make sure path really exists and resolve to absolute path |
| |
207 if posix.stat(dir) == nil then |
| |
208 io.stderr:write("rpm: creating \"" .. arg.variable .. "\" directory \"" .. dir .. "\"\n") |
| |
209 if posix.mkdir(dir) ~= 0 then |
| |
210 io.stderr:write("rpm: failed to create directory \"" .. dir .. "\"\n") |
| |
211 end |
| |
212 end |
| |
213 dir = openpkg.canonicalize(openpkg.realpath(dir)) |
| |
214 end |
| |
215 |
| |
216 -- debugging |
| |
217 if arg.debug == "yes" then |
| |
218 local variable = arg.variable |
| |
219 if arg_map_rev[variable] ~= nil then |
| |
220 variable = arg_map_rev[variable] |
| |
221 end |
| |
222 io.stderr:write(string.format("rpm: openpkg: layout: [%s] %s = \"%s\"\n", arg.layout, variable, dir)) |
| |
223 end |
| |
224 |
| |
225 -- provide result directory |
| |
226 return dir |
| |
227 end |
| |
228 |