pacman-key: rework importing distro/repo provided keyrings
[pacman-ng.git] / test / pacman / pmdb.py
blobb94c6cf6a8d6bb1bbb97c0016f496d96ebd13f7e
1 #! /usr/bin/python
3 # Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
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, see <http://www.gnu.org/licenses/>.
19 import os
20 import shutil
21 from StringIO import StringIO
22 import tarfile
24 import pmpkg
25 import util
27 def _getsection(fd):
28 i = []
29 while 1:
30 line = fd.readline().strip("\n")
31 if not line:
32 break
33 i.append(line)
34 return i
36 def make_section(data, title, values):
37 if not values:
38 return
39 data.append("%%%s%%" % title)
40 if isinstance(values, (list, tuple)):
41 data.extend(str(item) for item in values)
42 else:
43 # just a single value
44 data.append(str(values))
45 data.append('\n')
48 class pmdb(object):
49 """Database object
50 """
52 def __init__(self, treename, root):
53 self.treename = treename
54 self.root = root
55 self.pkgs = []
56 self.option = {}
57 if self.treename == "local":
58 self.dbdir = os.path.join(root, util.PM_DBPATH, treename)
59 self.dbfile = None
60 self.is_local = True
61 self.read_dircache = None
62 self.read_pkgcache = {}
63 else:
64 self.dbdir = None
65 self.dbfile = os.path.join(root, util.PM_SYNCDBPATH, treename + ".db")
66 self.is_local = False
68 def __str__(self):
69 return "%s" % self.treename
71 def getverify(self):
72 for value in ("Always", "Never", "Optional"):
73 if value in self.treename:
74 return value
75 return "Never"
77 def getpkg(self, name):
78 for pkg in self.pkgs:
79 if name == pkg.name:
80 return pkg
82 def db_read(self, name):
83 if not self.dbdir or not os.path.isdir(self.dbdir):
84 return None
86 dbentry = None
87 if self.read_dircache is None:
88 self.read_dircache = os.listdir(self.dbdir)
89 for entry in self.read_dircache:
90 [pkgname, pkgver, pkgrel] = entry.rsplit("-", 2)
91 if pkgname == name:
92 dbentry = entry
93 break
94 if dbentry is None:
95 return None
97 if pkgname in self.read_pkgcache:
98 return self.read_pkgcache[pkgname]
100 pkg = pmpkg.pmpkg(pkgname, pkgver + "-" + pkgrel)
101 self.read_pkgcache[pkgname] = pkg
103 path = os.path.join(self.dbdir, dbentry)
104 # desc
105 filename = os.path.join(path, "desc")
106 if not os.path.isfile(filename):
107 print "invalid db entry found (desc missing) for pkg", pkgname
108 return None
109 fd = open(filename, "r")
110 while 1:
111 line = fd.readline()
112 if not line:
113 break
114 line = line.strip("\n")
115 if line == "%DESC%":
116 pkg.desc = fd.readline().strip("\n")
117 elif line == "%GROUPS%":
118 pkg.groups = _getsection(fd)
119 elif line == "%URL%":
120 pkg.url = fd.readline().strip("\n")
121 elif line == "%LICENSE%":
122 pkg.license = _getsection(fd)
123 elif line == "%ARCH%":
124 pkg.arch = fd.readline().strip("\n")
125 elif line == "%BUILDDATE%":
126 pkg.builddate = fd.readline().strip("\n")
127 elif line == "%INSTALLDATE%":
128 pkg.installdate = fd.readline().strip("\n")
129 elif line == "%PACKAGER%":
130 pkg.packager = fd.readline().strip("\n")
131 elif line == "%REASON%":
132 try:
133 pkg.reason = int(fd.readline().strip("\n"))
134 except ValueError:
135 pkg.reason = -1
136 raise
137 elif line == "%SIZE%" or line == "%CSIZE%":
138 try:
139 pkg.size = int(fd.readline().strip("\n"))
140 except ValueError:
141 pkg.size = -1
142 raise
143 elif line == "%MD5SUM%":
144 pkg.md5sum = fd.readline().strip("\n")
145 elif line == "%PGPSIG%":
146 pkg.pgpsig = fd.readline().strip("\n")
147 elif line == "%REPLACES%":
148 pkg.replaces = _getsection(fd)
149 elif line == "%DEPENDS%":
150 pkg.depends = _getsection(fd)
151 elif line == "%OPTDEPENDS%":
152 pkg.optdepends = _getsection(fd)
153 elif line == "%CONFLICTS%":
154 pkg.conflicts = _getsection(fd)
155 elif line == "%PROVIDES%":
156 pkg.provides = _getsection(fd)
157 fd.close()
159 # files
160 filename = os.path.join(path, "files")
161 if not os.path.isfile(filename):
162 print "invalid db entry found (files missing) for pkg", pkgname
163 return None
164 fd = open(filename, "r")
165 while 1:
166 line = fd.readline()
167 if not line:
168 break
169 line = line.strip("\n")
170 if line == "%FILES%":
171 while line:
172 line = fd.readline().strip("\n")
173 if line and line[-1] != "/":
174 pkg.files.append(line)
175 if line == "%BACKUP%":
176 pkg.backup = _getsection(fd)
177 fd.close()
179 # install
180 filename = os.path.join(path, "install")
182 return pkg
185 # db_write is used to add both 'local' and 'sync' db entries
187 def db_write(self, pkg):
188 entry = {}
189 # desc/depends type entries
190 data = []
191 make_section(data, "NAME", pkg.name)
192 make_section(data, "VERSION", pkg.version)
193 make_section(data, "DESC", pkg.desc)
194 make_section(data, "GROUPS", pkg.groups)
195 make_section(data, "LICENSE", pkg.license)
196 make_section(data, "ARCH", pkg.arch)
197 make_section(data, "BUILDDATE", pkg.builddate)
198 make_section(data, "PACKAGER", pkg.packager)
199 make_section(data, "DEPENDS", pkg.depends)
200 make_section(data, "OPTDEPENDS", pkg.optdepends)
201 make_section(data, "CONFLICTS", pkg.conflicts)
202 make_section(data, "PROVIDES", pkg.provides)
203 make_section(data, "URL", pkg.url)
204 if self.is_local:
205 make_section(data, "INSTALLDATE", pkg.installdate)
206 make_section(data, "SIZE", pkg.size)
207 make_section(data, "REASON", pkg.reason)
208 else:
209 make_section(data, "FILENAME", pkg.filename())
210 make_section(data, "REPLACES", pkg.replaces)
211 make_section(data, "CSIZE", pkg.csize)
212 make_section(data, "ISIZE", pkg.isize)
213 make_section(data, "MD5SUM", pkg.md5sum)
214 make_section(data, "PGPSIG", pkg.pgpsig)
216 entry["desc"] = "\n".join(data)
218 # files and install
219 if self.is_local:
220 data = []
221 make_section(data, "FILES", pkg.full_filelist())
222 make_section(data, "BACKUP", pkg.local_backup_entries())
223 entry["files"] = "\n".join(data)
225 if any(pkg.install.values()):
226 entry["install"] = pkg.installfile()
228 return entry
230 def generate(self):
231 pkg_entries = [(pkg, self.db_write(pkg)) for pkg in self.pkgs]
233 if self.dbdir:
234 for pkg, entry in pkg_entries:
235 path = os.path.join(self.dbdir, pkg.fullname())
236 util.mkdir(path)
237 for name, data in entry.iteritems():
238 util.mkfile(path, name, data)
240 if self.dbfile:
241 tar = tarfile.open(self.dbfile, "w:gz")
242 for pkg, entry in pkg_entries:
243 # TODO: the addition of the directory is currently a
244 # requirement for successful reading of a DB by libalpm
245 info = tarfile.TarInfo(pkg.fullname())
246 info.type = tarfile.DIRTYPE
247 tar.addfile(info)
248 for name, data in entry.iteritems():
249 filename = os.path.join(pkg.fullname(), name)
250 info = tarfile.TarInfo(filename)
251 info.size = len(data)
252 tar.addfile(info, StringIO(data))
253 tar.close()
254 # TODO: this is a bit unnecessary considering only one test uses it
255 serverpath = os.path.join(self.root, util.SYNCREPO, self.treename)
256 util.mkdir(serverpath)
257 shutil.copy(self.dbfile, serverpath)
259 # vim: set ts=4 sw=4 et: