Rev 4134: (robertc) Add Revision.iter_bugs() method for getting bugs fixed by a in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Mar 12 13:03:21 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4134
revision-id: pqm at pqm.ubuntu.com-20090312130316-vmqowmbcu2tzynem
parent: pqm at pqm.ubuntu.com-20090312120049-uxdmf2dfelp5ctva
parent: jml at canonical.com-20090312081741-jnbcc7y5uzl3wq3u
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-03-12 13:03:16 +0000
message:
  (robertc) Add Revision.iter_bugs() method for getting bugs fixed by a
  	revision. (Jonathan Lange)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/bugtracker.py           bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
  bzrlib/tests/test_bugtracker.py test_bugtracker.py-20070410073305-vu1vu1qosjurg8kb-2
  bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
    ------------------------------------------------------------
    revno: 4119.4.5
    revision-id: jml at canonical.com-20090312081741-jnbcc7y5uzl3wq3u
    parent: jml at canonical.com-20090312073743-iiqlddlqawkjj92s
    committer: Jonathan Lange <jml at canonical.com>
    branch nick: bug-parsing
    timestamp: Thu 2009-03-12 18:17:41 +1000
    message:
      Fix the docstring.
    modified:
      bzrlib/bugtracker.py           bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
    ------------------------------------------------------------
    revno: 4119.4.4
    revision-id: jml at canonical.com-20090312073743-iiqlddlqawkjj92s
    parent: jml at canonical.com-20090312073517-z8di5cdnoydh6jcs
    committer: Jonathan Lange <jml at canonical.com>
    branch nick: bug-parsing
    timestamp: Thu 2009-03-12 17:37:43 +1000
    message:
      News, I guess
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 4119.4.3
    revision-id: jml at canonical.com-20090312073517-z8di5cdnoydh6jcs
    parent: jml at canonical.com-20090312070618-h7obf9em8kfzqg37
    committer: Jonathan Lange <jml at canonical.com>
    branch nick: bug-parsing
    timestamp: Thu 2009-03-12 17:35:17 +1000
    message:
      Add Revision.iter_bugs.
    modified:
      bzrlib/bugtracker.py           bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
      bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
    ------------------------------------------------------------
    revno: 4119.4.2
    revision-id: jml at canonical.com-20090312070618-h7obf9em8kfzqg37
    parent: jml at canonical.com-20090312070053-01k6mbe93frhp9qc
    committer: Jonathan Lange <jml at canonical.com>
    branch nick: bug-parsing
    timestamp: Thu 2009-03-12 17:06:18 +1000
    message:
      Some refactoring, some unit tests.
    modified:
      bzrlib/bugtracker.py           bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
      bzrlib/tests/test_bugtracker.py test_bugtracker.py-20070410073305-vu1vu1qosjurg8kb-2
    ------------------------------------------------------------
    revno: 4119.4.1
    revision-id: jml at canonical.com-20090312070053-01k6mbe93frhp9qc
    parent: pqm at pqm.ubuntu.com-20090312001649-6tvc2mmeyw992st3
    committer: Jonathan Lange <jml at canonical.com>
    branch nick: bug-parsing
    timestamp: Thu 2009-03-12 17:00:53 +1000
    message:
      Extract bug fix encoding logic from commit.
    modified:
      bzrlib/bugtracker.py           bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
=== modified file 'NEWS'
--- a/NEWS	2009-03-12 12:00:49 +0000
+++ b/NEWS	2009-03-12 13:03:16 +0000
@@ -93,6 +93,9 @@
       branch in your web browser, as long as the branch is on Launchpad at all.
       (Jonathan Lange)
 
+    * New API for getting bugs fixed by a revision: Revision.iter_bugs().
+      (Jonathan Lange)
+
   IMPROVEMENTS:
 
     * All bzr ``Hooks`` classes are now registered in

=== modified file 'bzrlib/bugtracker.py'
--- a/bzrlib/bugtracker.py	2009-03-11 00:30:33 +0000
+++ b/bzrlib/bugtracker.py	2009-03-12 08:17:41 +0000
@@ -282,3 +282,19 @@
 
 
 tracker_registry.register('generic', GenericBugTracker())
+
+
+FIXED = 'fixed'
+
+ALLOWED_BUG_STATUSES = set([FIXED])
+
+
+def encode_fixes_bug_urls(bug_urls):
+    """Get the revision property value for a commit that fixes bugs.
+
+    :param bug_urls: An iterable of escaped URLs to bugs. These normally
+        come from `get_bug_url`.
+    :return: A string that will be set as the 'bugs' property of a revision
+        as part of a commit.
+    """
+    return '\n'.join(('%s %s' % (url, FIXED)) for url in bug_urls)

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2009-03-12 12:00:49 +0000
+++ b/bzrlib/builtins.py	2009-03-12 13:03:16 +0000
@@ -2699,8 +2699,7 @@
              ]
     aliases = ['ci', 'checkin']
 
-    def _get_bug_fix_properties(self, fixes, branch):
-        properties = []
+    def _iter_bug_fix_urls(self, fixes, branch):
         # Configure the properties for bug fixing attributes.
         for fixed_bug in fixes:
             tokens = fixed_bug.split(':')
@@ -2711,15 +2710,13 @@
                     "feature.\nCommit refused." % fixed_bug)
             tag, bug_id = tokens
             try:
-                bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
+                yield bugtracker.get_bug_url(tag, branch, bug_id)
             except errors.UnknownBugTrackerAbbreviation:
                 raise errors.BzrCommandError(
                     'Unrecognized bug %s. Commit refused.' % fixed_bug)
             except errors.MalformedBugIdentifier, e:
                 raise errors.BzrCommandError(
                     "%s\nCommit refused." % (str(e),))
-            properties.append('%s fixed' % bug_url)
-        return '\n'.join(properties)
 
     def run(self, message=None, file=None, verbose=False, selected_list=None,
             unchanged=False, strict=False, local=False, fixes=None,
@@ -2752,7 +2749,8 @@
 
         if fixes is None:
             fixes = []
-        bug_property = self._get_bug_fix_properties(fixes, tree.branch)
+        bug_property = bugtracker.encode_fixes_bug_urls(
+            self._iter_bug_fix_urls(fixes, tree.branch))
         if bug_property:
             properties['bugs'] = bug_property
 

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2009-03-12 02:54:09 +0000
+++ b/bzrlib/errors.py	2009-03-12 13:03:16 +0000
@@ -2532,6 +2532,22 @@
         self.branch = branch
 
 
+class InvalidLineInBugsProperty(BzrError):
+
+    _fmt = ("Invalid line in bugs property: '%(line)s'")
+
+    def __init__(self, line):
+        self.line = line
+
+
+class InvalidBugStatus(BzrError):
+
+    _fmt = ("Invalid bug status: '%(status)s'")
+
+    def __init__(self, status):
+        self.status = status
+
+
 class UnexpectedSmartServerResponse(BzrError):
 
     _fmt = "Could not understand response from smart server: %(response_tuple)r"

=== modified file 'bzrlib/revision.py'
--- a/bzrlib/revision.py	2009-02-27 15:14:34 +0000
+++ b/bzrlib/revision.py	2009-03-12 07:35:17 +0000
@@ -21,6 +21,7 @@
 from bzrlib.lazy_import import lazy_import
 lazy_import(globals(), """
 from bzrlib import deprecated_graph
+from bzrlib import bugtracker
 """)
 from bzrlib import (
     errors,
@@ -140,6 +141,20 @@
         else:
             return authors.split("\n")
 
+    def iter_bugs(self):
+        """Iterate over the bugs associated with this revision."""
+        bug_property = self.properties.get('bugs', None)
+        if bug_property is None:
+            return
+        for line in bug_property.splitlines():
+            try:
+                url, status = line.split(None, 2)
+            except ValueError:
+                raise errors.InvalidLineInBugsProperty(line)
+            if status not in bugtracker.ALLOWED_BUG_STATUSES:
+                raise errors.InvalidBugStatus(status)
+            yield url, status
+
 
 def iter_ancestors(revision_id, revision_source, only_present=False):
     ancestors = (revision_id,)

=== modified file 'bzrlib/tests/test_bugtracker.py'
--- a/bzrlib/tests/test_bugtracker.py	2008-04-03 05:02:07 +0000
+++ b/bzrlib/tests/test_bugtracker.py	2009-03-12 07:06:18 +0000
@@ -16,7 +16,7 @@
 
 
 from bzrlib import bugtracker, errors, urlutils
-from bzrlib.tests import TestCaseWithMemoryTransport
+from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
 
 
 class TestGetBugURL(TestCaseWithMemoryTransport):
@@ -210,3 +210,22 @@
         """
         self.assertRaises(
             errors.MalformedBugIdentifier, self.tracker.get_bug_url, 'bad')
+
+
+class TestPropertyEncoding(TestCase):
+    """Tests for how the bug URLs are encoded as revision properties."""
+
+    def test_encoding_one(self):
+        self.assertEqual(
+            'http://example.com/bugs/1 fixed',
+            bugtracker.encode_fixes_bug_urls(['http://example.com/bugs/1']))
+
+    def test_encoding_zero(self):
+        self.assertEqual('', bugtracker.encode_fixes_bug_urls([]))
+
+    def test_encoding_two(self):
+        self.assertEqual(
+            'http://example.com/bugs/1 fixed\n'
+            'http://example.com/bugs/2 fixed',
+            bugtracker.encode_fixes_bug_urls(
+                ['http://example.com/bugs/1', 'http://example.com/bugs/2']))

=== modified file 'bzrlib/tests/test_revision.py'
--- a/bzrlib/tests/test_revision.py	2009-02-27 15:14:34 +0000
+++ b/bzrlib/tests/test_revision.py	2009-03-12 07:35:17 +0000
@@ -19,11 +19,16 @@
 import warnings
 
 from bzrlib import (
+    bugtracker,
     revision,
     symbol_versioning,
     )
 from bzrlib.branch import Branch
-from bzrlib.errors import NoSuchRevision
+from bzrlib.errors import (
+    InvalidBugStatus,
+    InvalidLineInBugsProperty,
+    NoSuchRevision,
+    )
 from bzrlib.deprecated_graph import Graph
 from bzrlib.revision import (find_present_ancestors,
                              NULL_REVISION)
@@ -231,3 +236,37 @@
         self.assertEqual(['B'], r.get_apparent_authors())
         r.properties['authors'] = 'C\nD'
         self.assertEqual(['C', 'D'], r.get_apparent_authors())
+
+
+class TestRevisionBugs(TestCase):
+    """Tests for getting the bugs that a revision is linked to."""
+
+    def test_no_bugs(self):
+        r = revision.Revision('1')
+        self.assertEqual([], list(r.iter_bugs()))
+
+    def test_some_bugs(self):
+        r = revision.Revision(
+            '1', properties={
+                'bugs': bugtracker.encode_fixes_bug_urls(
+                    ['http://example.com/bugs/1',
+                     'http://launchpad.net/bugs/1234'])})
+        self.assertEqual(
+            [('http://example.com/bugs/1', bugtracker.FIXED),
+             ('http://launchpad.net/bugs/1234', bugtracker.FIXED)],
+            list(r.iter_bugs()))
+
+    def test_no_status(self):
+        r = revision.Revision(
+            '1', properties={'bugs': 'http://example.com/bugs/1'})
+        self.assertRaises(InvalidLineInBugsProperty, list, r.iter_bugs())
+
+    def test_too_much_information(self):
+        r = revision.Revision(
+            '1', properties={'bugs': 'http://example.com/bugs/1 fixed bar'})
+        self.assertRaises(InvalidLineInBugsProperty, list, r.iter_bugs())
+
+    def test_invalid_status(self):
+        r = revision.Revision(
+            '1', properties={'bugs': 'http://example.com/bugs/1 faxed'})
+        self.assertRaises(InvalidBugStatus, list, r.iter_bugs())




More information about the bazaar-commits mailing list