_alpm_checkconflicts split
[pacman.git] / pactest / pmdb.py
blobf927b4b82aace1286ee21116f5d9a3e89ae1b2cb
1 #! /usr/bin/python
3 # Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 # USA.
21 import os
22 import tempfile
23 import shutil
25 import pmpkg
26 from util import *
29 def _mkfilelist(files):
30 """Generate a list of files from the list supplied as an argument.
32 Each path is decomposed to generate the list of all directories leading
33 to the file.
35 Example with 'usr/local/bin/dummy':
36 The resulting list will be
37 usr/
38 usr/local/
39 usr/local/bin/
40 usr/local/bin/dummy
41 """
42 i = []
43 for f in files:
44 dir = getfilename(f)
45 i.append(dir)
46 while "/" in dir:
47 [dir, tmp] = dir.rsplit("/", 1)
48 if not dir + "/" in files:
49 i.append(dir + "/")
50 i.sort()
51 return i
53 def _mkbackuplist(backup):
54 """
55 """
56 return ["%s\t%s" % (getfilename(i), mkmd5sum(i)) for i in backup]
58 def _getsection(fd):
59 """
60 """
61 i = []
62 while 1:
63 line = fd.readline().strip("\n")
64 if not line:
65 break
66 i.append(line)
67 return i
69 def _mksection(title, data):
70 """
71 """
72 s = ""
73 if isinstance(data, list):
74 s = "\n".join(data)
75 else:
76 s = data
77 return "%%%s%%\n" \
78 "%s\n" % (title, s)
81 class pmdb:
82 """Database object
83 """
85 def __init__(self, treename, dbdir):
86 self.treename = treename
87 self.dbdir = dbdir
88 self.pkgs = []
90 def __str__(self):
91 return "%s" % self.treename
93 def getpkg(self, name):
94 """
95 """
96 for pkg in self.pkgs:
97 if name == pkg.name:
98 return pkg
100 def db_read(self, name):
104 path = os.path.join(self.dbdir, self.treename)
105 if not os.path.isdir(path):
106 return None
108 dbentry = ""
109 for roots, dirs, files in os.walk(path):
110 for i in dirs:
111 [pkgname, pkgver, pkgrel] = i.rsplit("-", 2)
112 if pkgname == name:
113 dbentry = i
114 break
115 if not dbentry:
116 return None
117 path = os.path.join(path, dbentry)
119 [pkgname, pkgver, pkgrel] = dbentry.rsplit("-", 2)
120 pkg = pmpkg.pmpkg(pkgname, pkgver + "-" + pkgrel)
122 # desc
123 filename = os.path.join(path, "desc")
124 fd = file(filename, "r")
125 while 1:
126 line = fd.readline()
127 if not line:
128 break
129 line = line.strip("\n")
130 if line == "%DESC%":
131 pkg.desc = fd.readline().strip("\n")
132 elif line == "%GROUPS%":
133 pkg.groups = _getsection(fd)
134 elif line == "%URL%":
135 pkg.url = fd.readline().strip("\n")
136 elif line == "%LICENSE%":
137 pkg.license = _getsection(fd)
138 elif line == "%ARCH%":
139 pkg.arch = fd.readline().strip("\n")
140 elif line == "%BUILDDATE%":
141 pkg.builddate = fd.readline().strip("\n")
142 elif line == "%INSTALLDATE%":
143 pkg.installdate = fd.readline().strip("\n")
144 elif line == "%PACKAGER%":
145 pkg.packager = fd.readline().strip("\n")
146 elif line == "%REASON%":
147 pkg.reason = int(fd.readline().strip("\n"))
148 elif line == "%SIZE%" or line == "%CSIZE%":
149 pkg.size = int(fd.readline().strip("\n"))
150 elif line == "%MD5SUM%":
151 pkg.md5sum = fd.readline().strip("\n")
152 elif line == "%REPLACES%":
153 pkg.replaces = _getsection(fd)
154 elif line == "%FORCE%":
155 fd.readline()
156 pkg.force = 1
157 fd.close()
158 pkg.checksum["desc"] = getmd5sum(filename)
159 pkg.mtime["desc"] = getmtime(filename)
161 # files
162 filename = os.path.join(path, "files")
163 fd = file(filename, "r")
164 while 1:
165 line = fd.readline()
166 if not line:
167 break
168 line = line.strip("\n")
169 if line == "%FILES%":
170 while line:
171 line = fd.readline().strip("\n")
172 if line and line[-1] != "/":
173 pkg.files.append(line)
174 if line == "%BACKUP%":
175 pkg.backup = _getsection(fd)
176 fd.close()
177 pkg.checksum["files"] = getmd5sum(filename)
178 pkg.mtime["files"] = getmtime(filename)
180 # depends
181 filename = os.path.join(path, "depends")
182 fd = file(filename, "r")
183 while 1:
184 line = fd.readline()
185 if not line:
186 break
187 line = line.strip("\n")
188 if line == "%DEPENDS%":
189 pkg.depends = _getsection(fd)
190 elif line == "%OPTDEPENDS%":
191 pkg.optdepends = _getsection(fd)
192 elif line == "%CONFLICTS%":
193 pkg.conflicts = _getsection(fd)
194 elif line == "%PROVIDES%":
195 pkg.provides = _getsection(fd)
196 # TODO this was going to be changed, but isn't anymore
197 #elif line == "%REPLACES%":
198 # pkg.replaces = _getsection(fd)
199 #elif line == "%FORCE%":
200 # fd.readline()
201 # pkg.force = 1
202 fd.close()
203 pkg.checksum["depends"] = getmd5sum(filename)
204 pkg.mtime["depends"] = getmtime(filename)
206 # install
207 filename = os.path.join(path, "install")
208 if os.path.isfile(filename):
209 pkg.checksum["install"] = getmd5sum(filename)
210 pkg.mtime["install"] = getmtime(filename)
212 return pkg
215 # db_write is used to add both 'local' and 'sync' db entries
217 def db_write(self, pkg):
221 if self.treename == "local":
222 path = os.path.join(self.dbdir, self.treename, pkg.fullname())
223 else:
224 path = os.path.join(self.dbdir, "sync", self.treename, pkg.fullname())
225 mkdir(path)
227 # desc
228 # for local db entries: name, version, desc, groups, url, license,
229 # arch, builddate, installdate, packager,
230 # size, reason
231 # for sync entries: name, version, desc, groups, csize, md5sum,
232 # replaces, force
233 data = [_mksection("NAME", pkg.name)]
234 data.append(_mksection("VERSION", pkg.version))
235 if pkg.desc:
236 data.append(_mksection("DESC", pkg.desc))
237 if pkg.groups:
238 data.append(_mksection("GROUPS", pkg.groups))
239 if self.treename == "local":
240 if pkg.url:
241 data.append(_mksection("URL", pkg.url))
242 if pkg.license:
243 data.append(_mksection("LICENSE", pkg.license))
244 if pkg.arch:
245 data.append(_mksection("ARCH", pkg.arch))
246 if pkg.builddate:
247 data.append(_mksection("BUILDDATE", pkg.builddate))
248 if pkg.installdate:
249 data.append(_mksection("INSTALLDATE", pkg.installdate))
250 if pkg.packager:
251 data.append(_mksection("PACKAGER", pkg.packager))
252 if pkg.size:
253 data.append(_mksection("SIZE", pkg.size))
254 if pkg.reason:
255 data.append(_mksection("REASON", pkg.reason))
256 else:
257 if pkg.replaces:
258 data.append(_mksection("REPLACES", pkg.replaces))
259 if pkg.force:
260 data.append(_mksection("FORCE", ""))
261 if pkg.csize:
262 data.append(_mksection("CSIZE", pkg.csize))
263 if pkg.md5sum:
264 data.append(_mksection("MD5SUM", pkg.md5sum))
265 if data:
266 data.append("")
267 filename = os.path.join(path, "desc")
268 mkfile(filename, "\n".join(data))
269 pkg.checksum["desc"] = getmd5sum(filename)
270 pkg.mtime["desc"] = getmtime(filename)
272 # files
273 # for local entries, fields are: files, backup
274 # for sync ones: none
275 if self.treename == "local":
276 data = []
277 if pkg.files:
278 data.append(_mksection("FILES", _mkfilelist(pkg.files)))
279 if pkg.backup:
280 data.append(_mksection("BACKUP", _mkbackuplist(pkg.backup)))
281 if data:
282 data.append("")
283 filename = os.path.join(path, "files")
284 mkfile(filename, "\n".join(data))
285 pkg.checksum["files"] = getmd5sum(filename)
286 pkg.mtime["files"] = getmtime(filename)
288 # depends
289 # for local db entries: depends, conflicts, provides
290 # for sync ones: depends, conflicts, provides
291 data = []
292 if pkg.depends:
293 data.append(_mksection("DEPENDS", pkg.depends))
294 if pkg.optdepends:
295 data.append(_mksection("OPTDEPENDS", pkg.optdepends))
296 if pkg.conflicts:
297 data.append(_mksection("CONFLICTS", pkg.conflicts))
298 if pkg.provides:
299 data.append(_mksection("PROVIDES", pkg.provides))
300 #if self.treename != "local":
301 # if pkg.replaces:
302 # data.append(_mksection("REPLACES", pkg.replaces))
303 # if pkg.force:
304 # data.append(_mksection("FORCE", ""))
305 if data:
306 data.append("")
307 filename = os.path.join(path, "depends")
308 mkfile(filename, "\n".join(data))
309 pkg.checksum["depends"] = getmd5sum(filename)
310 pkg.mtime["depends"] = getmtime(filename)
312 # install
313 if self.treename == "local":
314 empty = 1
315 for value in pkg.install.values():
316 if value:
317 empty = 0
318 if not empty:
319 filename = os.path.join(path, "install")
320 mkinstallfile(filename, pkg.install)
321 pkg.checksum["install"] = getmd5sum(filename)
322 pkg.mtime["install"] = getmtime(filename)
324 def gensync(self, path):
328 curdir = os.getcwd()
329 tmpdir = tempfile.mkdtemp()
330 os.chdir(tmpdir)
332 for pkg in self.pkgs:
333 mkdescfile(pkg.fullname(), pkg)
335 # Generate database archive
336 mkdir(path)
337 archive = os.path.join(path, "%s%s" % (self.treename, PM_EXT_DB))
338 os.system("tar zcf %s *" % archive)
340 os.chdir(curdir)
341 shutil.rmtree(tmpdir)
343 def ispkgmodified(self, pkg):
347 modified = 0
349 oldpkg = self.getpkg(pkg.name)
350 if not oldpkg:
351 return 0
353 vprint("\toldpkg.checksum : %s" % oldpkg.checksum)
354 vprint("\toldpkg.mtime : %s" % oldpkg.mtime)
356 for key in pkg.mtime.keys():
357 if key == "install" \
358 and oldpkg.mtime[key] == (0, 0, 0) \
359 and pkg.mtime[key] == (0, 0, 0):
360 continue
361 if oldpkg.mtime[key][1:3] != pkg.mtime[key][1:3]:
362 modified += 1
364 return modified
367 if __name__ == "__main__":
368 db = pmdb("local")
369 print db
370 # vim: set ts=4 sw=4 et: