projects/aports·blob v2.11.1 · refs

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