projects/aports·blob v2.14.1 · refs

296 lines · 5.7 KiB

1module(..., package.seeall)
2
3abuild_conf_file = "/etc/abuild.conf"
4
5local abuild_conf = {}
6
7function get_abuild_conf(var)
8 -- check cache
9 if abuild_conf[var] ~= nil then
10 return abuild_conf[var]
11 end
12
13 -- use os env var
14 abuild_conf[var] = os.getenv(var)
15 if abuild_conf[var] ~= nil then
16 return abuild_conf[var]
17 end
18
19 -- parse config file
20 local f = io.popen(" . "..abuild_conf_file..' ; echo -n "$'..var..'"')
21 abuild_conf[var] = f:read("*all")
22 f:close()
23 return abuild_conf[var]
24end
25
26local function split_subpkgs(str)
27 local t = {}
28 local e
29 if (str == nil) then
30 return nil
31 end
32 for e in string.gmatch(str, "%S+") do
33 t[#t + 1] = string.gsub(e, ":.*", "")
34 end
35 return t
36end
37
38local function split(str)
39 local t = {}
40 local e
41 if (str == nil) then
42 return nil
43 end
44 for e in string.gmatch(str, "%S+") do
45 t[#t + 1] = e
46 end
47 return t
48end
49
50local function split_apkbuild(line)
51 local r = {}
52 local dir,pkgname, pkgver, pkgrel, arch, depends, makedepends, subpackages, source, url = string.match(line, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)")
53 r.dir = dir
54 r.pkgname = pkgname
55 r.pkgver = pkgver
56 r.pkgrel = pkgrel
57 r.depends = split(depends)
58 r.makedepends = split(makedepends)
59 r.subpackages = split_subpkgs(subpackages)
60 r.source = split(source)
61 r.url = url
62 return r
63end
64
65-- parse the APKBUILDs and return an iterator
66local function parse_apkbuilds(dirs)
67 local i,v, p
68 local str=""
69 if dirs == nil then
70 return nil
71 end
72 --expand repos
73 for i,v in ipairs(dirs) do
74 str = str..v.."/*/APKBUILD "
75 end
76
77 local p = io.popen([[
78 for i in ]]..str..[[; do
79 pkgname=
80 pkgver=
81 pkgrel=
82 arch=
83 depends=
84 makedepends=
85 subpackages=
86 source=
87 url=
88 dir="${i%/APKBUILD}"
89 cd "$dir"
90 . ./APKBUILD
91 echo $dir\|$pkgname\|$pkgver\|$pkgrel\|$arch\|$depends\|$makedepends\|$subpackages\|$source\|$url
92 done
93 ]])
94 return function()
95 local line = p:read("*line")
96 if line == nil then
97 p:close()
98 return nil
99 end
100 return split_apkbuild(line)
101 end
102end
103
104
105
106-- return a key list with makedepends and depends
107function all_deps(p)
108 local m = {}
109 local k,v
110 if p == nil then
111 return m
112 end
113 if type(p.depends) == "table" then
114 for k,v in pairs(p.depends) do
115 m[v] = true
116 end
117 end
118 if type(p.makedepends) == "table" then
119 for k,v in pairs(p.makedepends) do
120 m[v] = true
121 end
122 end
123 return m
124end
125
126function is_remote(url)
127 local _,pref
128 for _,pref in pairs{ "^http://", "^ftp://", "^https://", ".*::.*" } do
129 if string.match(url, pref) then
130 return true
131 end
132 end
133 return false
134end
135
136-- iterate over all entries in source and execute the function for remote
137function foreach_remote_source(p, func)
138 local _,s
139 if p == nil or type(p.source) ~= "table" then
140 return
141 end
142 for _,url in pairs(p.source) do
143 if is_remote(url) then
144 func(url)
145 end
146 end
147end
148
149function get_maintainer(pkg)
150 if pkg == nil or pkg.dir == nil then
151 return nil
152 end
153 local f = io.open(pkg.dir.."/APKBUILD")
154 if f == nil then
155 return nil
156 end
157 local line
158 for line in f:lines() do
159 local maintainer = line:match("^%s*#%s*Maintainer:%s*(.*)")
160 if maintainer then
161 f:close()
162 return maintainer
163 end
164 end
165 f:close()
166 return nil
167end
168
169function get_repo_name(pkg)
170 if pkg == nil or pkg.dir == nil then
171 return nil
172 end
173 return string.match(pkg.dir, ".*/(.*)/.*")
174end
175
176function get_apk_filename(pkg)
177 return pkg.pkgname.."-"..pkg.pkgver.."-r"..pkg.pkgrel..".apk"
178end
179
180function get_apk_file_path(pkg)
181 local pkgdest = get_abuild_conf("PKGDEST")
182 if pkgdest ~= nil and pkgdest ~= "" then
183 return pkgdest.."/"..get_apk_filename(pkg)
184 end
185 local repodest = get_abuild_conf("REPODEST")
186 if repodest ~= nil and repodest ~= "" then
187 local arch = get_abuild_conf("CARCH")
188 return repodest.."/"..get_repo_name(pkg).."/"..arch.."/"..get_apk_filename(pkg)
189 end
190 return pkg.dir.."/"..get_apk_filename(pkg)
191end
192
193
194local function init_apkdb(repodirs)
195 local pkgdb = {}
196 local revdeps = {}
197 local a
198 for a in parse_apkbuilds(repodirs) do
199 -- io.write(a.pkgname.." "..a.pkgver.."\t"..a.dir.."\n")
200 if pkgdb[a.pkgname] == nil then
201 pkgdb[a.pkgname] = {}
202 end
203 a.all_deps = all_deps
204 table.insert(pkgdb[a.pkgname], a)
205 -- add subpackages to package db
206 local k,v
207 for k,v in pairs(a.subpackages) do
208 if pkgdb[v] == nil then
209 pkgdb[v] = {}
210 end
211 table.insert(pkgdb[v], a)
212 end
213 -- add to reverse dependencies
214 for v in pairs(all_deps(a)) do
215 if revdeps[v] == nil then
216 revdeps[v] = {}
217 end
218 table.insert(revdeps[v], a)
219 end
220 end
221 return pkgdb, revdeps
222end
223
224local Aports = {}
225function Aports:recurs_until(pn, func)
226 local visited={}
227 local apkdb = self.apks
228 function recurs(pn)
229 if pn == nil or visited[pn] or apkdb[pn] == nil then
230 return false
231 end
232 visited[pn] = true
233 local _, p
234 for _, p in pairs(apkdb[pn]) do
235 local d
236 for d in pairs(all_deps(p)) do
237 if recurs(d) then
238 return true
239 end
240 end
241 end
242 return func(pn)
243 end
244 return recurs(pn)
245end
246
247function Aports:target_packages(pkgname)
248 local i,v
249 local t = {}
250 for k,v in pairs(self.apks[pkgname]) do
251 table.insert(t, pkgname.."-"..v.pkgver.."-r"..v.pkgrel..".apk")
252 end
253 return t
254end
255
256function Aports:foreach(f)
257 local k,v
258 for k,v in pairs(self.apks) do
259 f(k,v)
260 end
261end
262
263function Aports:foreach_revdep(pkg, f)
264 local k,v
265 for k,v in pairs(self.revdeps[pkg] or {}) do
266 f(k,v)
267 end
268end
269
270function Aports:foreach_pkg(pkg, f)
271 local k,v
272 if self.apks[pkg] == nil then
273 io.stderr:write("WARNING: "..pkg.." has no data\n")
274 end
275 for k,v in pairs(self.apks[pkg]) do
276 f(k,v)
277 end
278end
279
280function Aports:foreach_aport(f)
281 self:foreach(function(pkgname)
282 self:foreach_pkg(pkgname, function(i, pkg)
283 if pkgname == pkg.pkgname then
284 f(pkg)
285 end
286 end)
287 end)
288end
289
290function new(repodirs)
291 local h = Aports
292 h.repodirs = repodirs
293 h.apks, h.revdeps = init_apkdb(repodirs)
294 return h
295end
296