Rev 1: Create a plugin for graphing kndx files. in http://bzr.arbash-meinel.com/plugins/kndx_to_dot

John Arbash Meinel john at arbash-meinel.com
Tue Apr 10 22:29:02 BST 2007


At http://bzr.arbash-meinel.com/plugins/kndx_to_dot

------------------------------------------------------------
revno: 1
revision-id: john at arbash-meinel.com-20070410212858-a31k4bi6j37h3okb
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: kndx_to_dot
timestamp: Tue 2007-04-10 16:28:58 -0500
message:
  Create a plugin for graphing kndx files.
added:
  __init__.py                    __init__.py-20070410212739-0uwundx7uoho7f6n-1
-------------- next part --------------
=== added file '__init__.py'
--- a/__init__.py	1970-01-01 00:00:00 +0000
+++ b/__init__.py	2007-04-10 21:28:58 +0000
@@ -0,0 +1,119 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""A plugin to help graphing the history in a knit file."""
+
+from bzrlib import (
+    commands,
+    knit,
+    lazy_regex,
+    option,
+    transport,
+    urlutils,
+    )
+
+
+class cmd_kndx2dot(commands.Command):
+    """Generate the 'dot' graph for a given knit index.
+
+    You can specify revisions to restrict the graph with --start and --end.
+    start and end can either be revision ids, or they can be integers
+    indicating the offset in the inventory file.
+
+    The knit file should be specified without an extension. So
+    '.bzr/repository/inventory.kndx' is specified as
+    '.bzr/repository/inventory'.
+    """
+
+    _revision_id_re = lazy_regex.lazy_compile(
+        r'(?P<user>.+)'
+        r'@.*'
+        r'-20(?P<date>\d{6})(?P<time>\d{6})-'
+        r'.*(?P<tail>[a-z0-9]{5})$')
+
+    takes_args = ['path']
+    takes_options = [option.Option('start', type=str, argname='revid',
+                           help='Don\'t include revision before this one.'),
+                     option.Option('end', type=str, argname='revid',
+                           help='Don\'t include revision after this one.'),
+                     option.Option('short',
+                           help='Hack up short names for revisions so the'
+                                ' graph is less unweildy.')
+                    ]
+
+    def run(self, path, start=None, end=None, short=False):
+        t = transport.get_transport(path)
+        _, knit_name = urlutils.split(t.base)
+        t = t.clone('..')
+        a_knit = knit.KnitVersionedFile(knit_name, t, file_mode='r')
+        kndx = a_knit._index
+
+        versions = kndx.get_versions()
+        version_idxs = dict((v, o) for o, v in enumerate(versions))
+        if start is not None:
+            try:
+                versions = versions[int(start):]
+            except ValueError:
+                versions = versions[versions.index(start):]
+        if end is not None:
+            try:
+                versions = versions[:int(end)+1]
+            except ValueError:
+                versions = versions[:versions.index(end)+1]
+
+        self.outf.write('digraph T {\n'
+                        '  node [shape=box]\n'
+                       )
+
+        for version in versions:
+            if short:
+                sversion = self.make_short_name(version_idxs, version)
+            else:
+                sversion = version
+            parents = kndx.get_parents(version)
+            if short:
+                sparents = [self.make_short_name(version_idxs, p)
+                            for p in parents]
+            else:
+                sparents = parents
+            if not parents:
+                self.outf.write('  "%s"\n' % (sversion,))
+            else:
+                for sparent in sparents:
+                    self.outf.write('  "%s" -> "%s"\n' % (sparent, sversion))
+            # elif len(parents) == 1:
+            #     self.outf.write('  "%s" -> "%s"\n' % (sversion, sparents[0]))
+            # else:
+            #     sparents = ' '.join('"%s"' % p for p in sparents)
+            #     self.outf.write('  "%s" -> {%s}\n' % (sversion, sparents))
+        self.outf.write('}\n')
+
+    def make_short_name(self, version_idxs, version):
+        """Convert a revision id into a shorter name.
+
+        :param version_idxs: A dict mapping versions => offset
+        :param version: The version to shorten.
+        """
+        idx = version_idxs[version]
+        m = self._revision_id_re.match(version)
+        if m:
+            return "%s %s-%s-%s" % (idx, m.group('user'),
+                                    m.group('date'), m.group('tail'))
+        else:
+            return "%s %s" % (idx, version)
+
+
+commands.register_command(cmd_kndx2dot)



More information about the bazaar-commits mailing list