Eg. yum histry merge 1..2 => Will show the first two transactions
   as though they were a single transaction. All the complicated bits
   are in YumMergedTransaction.merge(), this is just a UI patch.
 Adds this to the man page.

 Also changes transaction time to have minutes/hours/days.

 Also fixes info's package name chopping to dtrt. for Obsoleting
packages.

 Also makes "history info" report an error if there are no transactions.
---
 docs/yum.8 |    9 ++++-
 output.py  |  133 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 125 insertions(+), 17 deletions(-)

diff --git a/docs/yum.8 b/docs/yum.8
index 7ac9772..4158453 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -247,7 +247,14 @@ and new to start a new history file.
 The info/list/summary commands take either a transactions id or a package (with
 wildcards, as in \fBSpecifying package names\fP), all three can also be passed
 no arguments. list can be passed the keyword "all" to list all the 
transactions.
-undo/redo just take a transaction id.
+undo/redo just take a transaction id\&.
+
+The info command can also take ranges of transaction ids, of the form
+start..end, which will then display a merged history as if all the
+transactions in the range had happened at once\&.
+.br
+Eg. "history info 1..4" will merge the first four transactions and display them
+as a single transaction.
 .IP
 .IP "\fBhelp\fP"
 Produces help, either for all commands or if given a command name then the help
diff --git a/output.py b/output.py
index 4a94bc4..25076f3 100755
--- a/output.py
+++ b/output.py
@@ -43,6 +43,8 @@ from yum.rpmtrans import RPMBaseCallback
 from yum.packageSack import packagesNewestByNameArch
 import yum.packages
 
+import yum.history
+
 from yum.i18n import utf8_width, utf8_width_fill, utf8_text_fill
 
 def _term_width():
@@ -1198,6 +1200,9 @@ to exit.
         return count, "".join(list(actions))
 
     def _pwd_ui_username(self, uid, limit=None):
+        if type(uid) == type([]):
+            return [self._pwd_ui_username(u, limit) for u in uid]
+
         # loginuid is set to -1 on init.
         if uid is None or uid == 0xFFFFFFFF:
             loginid = _("<unset>")
@@ -1317,21 +1322,58 @@ to exit.
         return old[0]
 
     def historyInfoCmd(self, extcmds):
+        def str2int(x):
+            try:
+                return int(x)
+            except ValueError:
+                return None
+
         tids = set()
+        mtids = set()
         pats = []
+        old = self.history.last()
+        if old is None:
+            self.logger.critical(_('No transactions'))
+            return 1, ['Failed history info']
+
         for tid in extcmds[1:]:
-            try:
-                int(tid)
-                tids.add(tid)
-            except ValueError:
-                pats.append(tid)
+            if '..' in tid:
+                btid, etid = tid.split('..', 2)
+                btid = str2int(btid)
+                if btid > old.tid:
+                    btid = None
+                elif btid <= 0:
+                    btid = None
+                etid = str2int(etid)
+                if etid > old.tid:
+                    etid = None
+                if btid is not None and etid is not None:
+                    # Have a range ... do a "merged" transaction.
+                    if btid > etid:
+                        btid, etid = etid, btid
+                    mtids.add((btid, etid))
+                    continue
+            elif str2int(tid) is not None:
+                tids.add(str2int(tid))
+                continue
+            pats.append(tid)
         if pats:
             tids.update(self.history.search(pats))
+        utids = tids.copy()
+        if mtids:
+            mtids = sorted(mtids)
+            last_end = -1 # This just makes displaying it easier...
+            for mtid in mtids:
+                if mtid[0] < last_end:
+                    self.logger.warn(_('Skipping merged transaction %d to %d, 
as it overlaps', mtid[0], mtid[1]))
+                    continue # Don't do overlapping
+                last_end = mtid[1]
+                for num in range(mtid[0], mtid[1] + 1):
+                    tids.add(num)
 
         if not tids and len(extcmds) < 2:
-            old = self.history.last()
-            if old is not None:
-                tids.add(old.tid)
+            tids.add(old.tid)
+            utids.add(old.tid)
 
         if not tids:
             self.logger.critical(_('No transaction ID, or package, given'))
@@ -1343,6 +1385,10 @@ to exit.
             lastdbv = lastdbv.end_rpmdbversion
 
         done = False
+        bmtid, emtid = -1, -1
+        mobj = None
+        if mtids:
+            bmtid, emtid = mtids.pop(0)
         for tid in self.history.old(tids):
             if lastdbv is not None and tid.tid == lasttid:
                 #  If this is the last transaction, is good and it doesn't
@@ -1352,15 +1398,43 @@ to exit.
                     tid.altered_gt_rpmdb = True
             lastdbv = None
 
+            if tid.tid >= bmtid and tid.tid <= emtid:
+                if mobj is None:
+                    mobj = yum.history.YumMergedHistoryTransaction(tid)
+                else:
+                    mobj.merge(tid)
+            elif mobj is not None:
+                if done:
+                    print "-" * 79
+                done = True
+
+                self._historyInfoCmd(mobj)
+                mobj = None
+                if mtids:
+                    bmtid, emtid = mtids.pop(0)
+                    if tid.tid >= bmtid and tid.tid <= emtid:
+                        mobj = yum.history.YumMergedHistoryTransaction(tid)
+
+            if tid.tid in utids:
+                if done:
+                    print "-" * 79
+                done = True
+
+                self._historyInfoCmd(tid, pats)
+
+        if mobj is not None:
             if done:
                 print "-" * 79
-            done = True
-            self._historyInfoCmd(tid, pats)
+
+            self._historyInfoCmd(mobj)
 
     def _historyInfoCmd(self, old, pats=[]):
         name = self._pwd_ui_username(old.loginuid)
 
-        print _("Transaction ID :"), old.tid
+        if type(old.tid) == type([]):
+            print _("Transaction ID :"), "%u..%u" % (old.tid[0], old.tid[-1])
+        else:
+            print _("Transaction ID :"), old.tid
         begtm = time.ctime(old.beg_timestamp)
         print _("Begin time     :"), begtm
         if old.beg_rpmdbversion is not None:
@@ -1381,15 +1455,34 @@ to exit.
                         break
                     sofar += len(begtms[i]) + 1
                 endtm = (' ' * sofar) + endtm[sofar:]
-            diff = _("(%s seconds)") % (old.end_timestamp - old.beg_timestamp)
+            diff = old.end_timestamp - old.beg_timestamp
+            if diff < 5 * 60:
+                diff = _("(%u seconds)") % diff
+            elif diff < 5 * 60 * 60:
+                diff = _("(%u minutes)") % (diff / 60)
+            elif diff < 5 * 60 * 60 * 24:
+                diff = _("(%u hours)") % (diff / (60 * 60))
+            else:
+                diff = _("(%u days)") % (diff / (60 * 60 * 24))
             print _("End time       :"), endtm, diff
         if old.end_rpmdbversion is not None:
             if old.altered_gt_rpmdb:
                 print _("End rpmdb      :"), old.end_rpmdbversion, "**"
             else:
                 print _("End rpmdb      :"), old.end_rpmdbversion
-        print _("User           :"), name
-        if old.return_code is None:
+        if type(name) == type([]):
+            for name in name:
+                print _("User           :"), name
+        else:
+            print _("User           :"), name
+        if type(old.return_code) == type([]):
+            codes = old.return_code
+            if codes[0] is None:
+                print _("Return-Code    :"), "**", _("Aborted"), "**"
+                codes = codes[1:]
+            if codes:
+                print _("Return-Code    :"), _("Failures:"), ", ".join(codes)
+        elif old.return_code is None:
             print _("Return-Code    :"), "**", _("Aborted"), "**"
         elif old.return_code:
             print _("Return-Code    :"), _("Failure:"), old.return_code
@@ -1428,6 +1521,7 @@ to exit.
                 print "%4d" % num, line
 
     def historyInfoCmdPkgsAltered(self, old, pats=[]):
+        last = None
         for hpkg in old.trans_data:
             prefix = " " * 4
             if not hpkg.done:
@@ -1459,15 +1553,22 @@ to exit.
             uistate = utf8_width_fill(uistate, 12, 12)
             # Should probably use columns here...
             if False: pass
-            elif hpkg.state == 'Update':
+            elif (last is not None and
+                  last.state == 'Updated' and last.name == hpkg.name and
+                  hpkg.state == 'Update'):
                 ln = len(hpkg.name) + 1
                 cn = (" " * ln) + cn[ln:]
                 print "%s%s%s%s %s" % (prefix, hibeg, uistate, hiend, cn)
-            elif hpkg.state == 'Downgraded':
+            elif (last is not None and
+                  last.state == 'Downgrade' and last.name == hpkg.name and
+                  hpkg.state == 'Downgraded'):
                 ln = len(hpkg.name) + 1
                 cn = (" " * ln) + cn[ln:]
                 print "%s%s%s%s %s" % (prefix, hibeg, uistate, hiend, cn)
             else:
+                last = None
+                if hpkg.state in ('Updated', 'Downgrade'):
+                    last = hpkg
                 print "%s%s%s%s %s" % (prefix, hibeg, uistate, hiend, cn)
 
     def historySummaryCmd(self, extcmds):
-- 
1.6.2.5

_______________________________________________
Yum-devel mailing list
Yum-devel@lists.baseurl.org
http://lists.baseurl.org/mailman/listinfo/yum-devel

Reply via email to