ts.check() is supposed to return empty list when no problems
[platform/upstream/rpm.git] / python / rpm / transaction.py
1 #!/usr/bin/python
2
3 import rpm
4 from rpm._rpm import ts as _rpmts
5
6 # TODO: migrate relevant documentation from C-side
7 class TransactionSet(_rpmts):
8     _probFilter = 0
9     # FIXME: kludge for keeping refcounts on transaction element keys
10     _keyList = []
11
12     def _wrapSetGet(self, attr, val):
13         oval = getattr(self, attr)
14         setattr(self, attr, val)
15         return oval
16         
17     def setVSFlags(self, flags):
18         return self._wrapSetGet('_vsflags', flags)
19
20     def getVSFlags(self):
21         return self._vsflags
22
23     def setColor(self, color):
24         return self._wrapSetGet('_color', color)
25
26     def setPrefColor(self, color):
27         return self._wrapSetGet('_prefcolor', color)
28
29     def setFlags(self, flags):
30         return self._wrapSetGet('_flags', flags)
31
32     def setProbFilter(self, ignoreSet):
33         return self._wrapSetGet('_probFilter', ignoreSet)
34
35     def parseSpec(self, specfile):
36         import _rpmb
37         return _rpmb.spec(specfile)
38
39     def getKeys(self):
40         keys = []
41         for te in self:
42             keys.append(te.Key())
43         # Backwards compatibility goo - WTH does this return a *tuple* ?!
44         if not keys:
45             return None
46         else:
47             return tuple(keys)
48
49     def addInstall(self, item, key, how="u"):
50         if isinstance(item, str):
51             f = file(item)
52             header = self.hdrFromFdno(f)
53             f.close()
54         elif isinstance(item, file):
55             header = self.hdrFromFdno(item)
56         else:
57             header = item
58
59         if not how in ['u', 'i']:
60             raise ValueError('how argument must be "u" or "i"')
61         upgrade = (how == "u")
62
63         if not _rpmts.addInstall(self, header, key, upgrade):
64             raise rpm.error("adding package to transaction failed")
65         self._keyList.append(key)
66
67     def addErase(self, item):
68         hdrs = []
69         if isinstance(item, rpm.hdr):
70             hdrs = [item]
71         elif isinstance(item, rpm.mi):
72             hdrs = item
73         elif isinstance(item, int):
74             hdrs = self.dbMatch(rpm.RPMDBI_PACKAGES, item)
75         elif isinstance(item, str):
76             hdrs = self.dbMatch(rpm.RPMDBI_LABEL, item)
77         else:
78             raise TypeError("invalid type %s" % type(item))
79
80         for h in hdrs:
81             if not _rpmts.addErase(self, h):
82                 raise rpm.error("package not installed")
83
84         # garbage collection should take care but just in case...
85         if isinstance(hdrs, rpm.mi):
86             del hdrs
87
88     def run(self, callback, data):
89         rc = _rpmts.run(self, callback, data, self._probFilter)
90
91         # crazy backwards compatibility goo: None for ok, list of problems
92         # if transaction didnt complete and empty list if it completed
93         # with errors
94         if rc == 0:
95             return None
96
97         res = []
98         if rc > 0:
99             for prob in self.problems():
100                 item = ("%s" % prob, (prob.type, prob._str, prob._num))
101                 res.append(item)
102         return res
103
104     def check(self, *args, **kwds):
105         _rpmts.check(self, *args, **kwds)
106
107         # compatibility: munge problem strings into dependency tuples of doom
108         res = []
109         for p in self.problems():
110             # is it anything we need to care about?
111             if p.type == rpm.RPMPROB_CONFLICT:
112                 sense = rpm.RPMDEP_SENSE_CONFLICTS
113             elif p.type == rpm.RPMPROB_REQUIRES:
114                 sense = rpm.RPMDEP_SENSE_REQUIRES
115             else:
116                 continue
117
118             # strip arch, split to name, version, release
119             nevr = p.pkgNEVR.rsplit('.', 1)[0]
120             n, v, r = nevr.rsplit('-', 2)
121
122             # extract the dependency information
123             needs = p.altNEVR.split()[1:]
124             needname = needs[0]
125             needflags = rpm.RPMSENSE_ANY
126             if len(needs) == 3:
127                 needop = needs[1]
128                 if needop.find('<') >= 0: needflags |= rpm.RPMSENSE_LESS
129                 if needop.find('=') >= 0: needflags |= rpm.RPMSENSE_EQUAL
130                 if needop.find('>') >= 0: needflags |= rpm.RPMSENSE_GREATER
131                 needver = needs[2]
132             else:
133                 needver = ""
134
135             res.append(((n, v, r),(needname,needver),needflags,sense,p.key))
136
137         return res
138
139     def hdrCheck(self, blob):
140         res, msg = _rpmts.hdrCheck(self, blob)
141         # generate backwards compatibly broken exceptions
142         if res == rpm.RPMRC_NOKEY:
143             raise rpm.error("public key not available")
144         elif res == rpm.RPMRC_NOTTRUSTED:
145             raise rpm.error("public key not trusted")
146         elif res != rpm.RPMRC_OK:
147             raise rpm.error(msg)
148
149     def hdrFromFdno(self, fd):
150         res, h = _rpmts.hdrFromFdno(self, fd)
151         # generate backwards compatibly broken exceptions
152         if res == rpm.RPMRC_NOKEY:
153             raise rpm.error("public key not available")
154         elif res == rpm.RPMRC_NOTTRUSTED:
155             raise rpm.error("public key not trusted")
156         elif res != rpm.RPMRC_OK:
157             raise rpm.error("error reading package header")
158
159         return h