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