Rev 4455: Initial api for Annotator. in http://bazaar.launchpad.net/~jameinel/bzr/1.17-rework-annotate

John Arbash Meinel john at arbash-meinel.com
Wed Jun 17 20:39:08 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr/1.17-rework-annotate

------------------------------------------------------------
revno: 4455
revision-id: john at arbash-meinel.com-20090617193858-y7qy0zhsxeoewoyd
parent: pqm at pqm.ubuntu.com-20090617100437-gavn9zkum4dj5yjz
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 1.17-rework-annotate
timestamp: Wed 2009-06-17 14:38:58 -0500
message:
  Initial api for Annotator.
  
  Currently just a thunk around the other annotation code.
  But it defines the api as returning multiple possible sources
  for each line. And separates the annotations into a separate
  list from the actual lines.
-------------- next part --------------
=== added file 'bzrlib/_annotator_py.py'
--- a/bzrlib/_annotator_py.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/_annotator_py.py	2009-06-17 19:38:58 +0000
@@ -0,0 +1,65 @@
+# Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Functionality for doing annotations in the 'optimal' way"""
+
+from bzrlib import (
+    annotate,
+    errors,
+    graph as _mod_graph,
+    osutils,
+    )
+
+
+class AnnotatorPolicy(object):
+    """Variables that define annotations."""
+
+
+class Annotator(object):
+    """Class that drives performing annotations."""
+
+    def __init__(self, vf):
+        """Create a new Annotator from a VersionedFile."""
+        self._vf = vf
+
+    def annotate(self, key):
+        """Return annotated fulltext for the given key."""
+        graph = _mod_graph.Graph(self._vf)
+        parent_map = dict((k, v) for k, v in graph.iter_ancestry([key])
+                          if v is not None)
+        if not parent_map:
+            raise errors.RevisionNotPresent(key, self)
+        keys = parent_map.keys()
+        heads_provider = _mod_graph.KnownGraph(parent_map)
+        parent_cache = {}
+        reannotate = annotate.reannotate
+        for record in self._vf.get_record_stream(keys, 'topological', True):
+            key = record.key
+            fulltext = osutils.chunks_to_lines(record.get_bytes_as('chunked'))
+            parents = parent_map[key]
+            if parents is not None:
+                parent_lines = [parent_cache[parent] for parent in parent_map[key]]
+            else:
+                parent_lines = []
+            parent_cache[key] = list(
+                reannotate(parent_lines, fulltext, key, None, heads_provider))
+        try:
+            annotated = parent_cache[key]
+        except KeyError, e:
+            raise errors.RevisionNotPresent(key, self._vf)
+        annotations = [(a,) for a,l in annotated]
+        lines = [l for a,l in annotated]
+        return annotations, lines

=== modified file 'bzrlib/annotate.py'
--- a/bzrlib/annotate.py	2009-04-08 13:13:30 +0000
+++ b/bzrlib/annotate.py	2009-06-17 19:38:58 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
+# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-06-10 18:58:02 +0000
+++ b/bzrlib/tests/__init__.py	2009-06-17 19:38:58 +0000
@@ -3344,6 +3344,7 @@
                    'bzrlib.tests.per_repository',
                    'bzrlib.tests.per_repository_chk',
                    'bzrlib.tests.per_repository_reference',
+                   'bzrlib.tests.test__annotator',
                    'bzrlib.tests.test__chk_map',
                    'bzrlib.tests.test__dirstate_helpers',
                    'bzrlib.tests.test__groupcompress',

=== added file 'bzrlib/tests/test__annotator.py'
--- a/bzrlib/tests/test__annotator.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test__annotator.py	2009-06-17 19:38:58 +0000
@@ -0,0 +1,85 @@
+# Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for Annotators."""
+
+from bzrlib import (
+    errors,
+    _annotator_py,
+    tests,
+    )
+
+
+def load_tests(standard_tests, module, loader):
+    """Parameterize tests for all versions of groupcompress."""
+    scenarios = [
+        ('python', {'module': _annotator_py}),
+    ]
+    suite = loader.suiteClass()
+    if CompiledAnnotator.available():
+        from bzrlib import _annotator_pyx
+        scenarios.append(('C', {'module': _annotator_pyx}))
+    else:
+        # the compiled module isn't available, so we add a failing test
+        class FailWithoutFeature(tests.TestCase):
+            def test_fail(self):
+                self.requireFeature(CompiledAnnotator)
+        suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
+    result = tests.multiply_tests(standard_tests, scenarios, suite)
+    return result
+
+
+class _CompiledAnnotator(tests.Feature):
+
+    def _probe(self):
+        try:
+            import bzrlib._annotator_pyx
+        except ImportError:
+            return False
+        return True
+
+    def feature_name(self):
+        return 'bzrlib._annotator_pyx'
+
+CompiledAnnotator = _CompiledAnnotator()
+
+
+class TestAnnotator(tests.TestCaseWithMemoryTransport):
+
+    module = None # Set by load_tests
+
+    def make_single_text(self):
+        repo = self.make_repository('repo')
+        repo.lock_write()
+        self.addCleanup(repo.unlock)
+        vf = repo.texts
+        repo.start_write_group()
+        vf.add_lines(('f-id', 'a-id'), (), ['simple\n', 'content\n'])
+        repo.commit_write_group()
+        return vf
+
+    def test_annotate_missing(self):
+        vf = self.make_single_text()
+        ann = self.module.Annotator(vf)
+        self.assertRaises(errors.RevisionNotPresent,
+                          ann.annotate, ('not', 'present'))
+
+    def test_annotate_simple(self):
+        vf = self.make_single_text()
+        ann = self.module.Annotator(vf)
+        f_key = ('f-id', 'a-id')
+        self.assertEqual(([(f_key,)]*2, ['simple\n', 'content\n']),
+                         ann.annotate(f_key))

=== modified file 'bzrlib/tests/test__known_graph.py'
--- a/bzrlib/tests/test__known_graph.py	2009-06-16 15:35:14 +0000
+++ b/bzrlib/tests/test__known_graph.py	2009-06-17 19:38:58 +0000
@@ -14,7 +14,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-"""Tests for the python and pyrex extensions of groupcompress"""
+"""Tests for the python and pyrex extensions of KnownGraph"""
 
 from bzrlib import (
     errors,



More information about the bazaar-commits mailing list