Rev 5106: (Jelmer) Add 'automatic_tag_name' hook. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Mar 22 19:02:45 GMT 2010


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

------------------------------------------------------------
revno: 5106 [merge]
revision-id: pqm at pqm.ubuntu.com-20100322190243-u13kk6705w4k38i9
parent: pqm at pqm.ubuntu.com-20100322113916-cwzfq5olk75uzs20
parent: jelmer at samba.org-20100322135933-7i7vyau8mvjoqvpf
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2010-03-22 19:02:43 +0000
message:
  (Jelmer) Add 'automatic_tag_name' hook.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/tag.py                  tag.py-20070212110532-91cw79inah2cfozx-1
  bzrlib/tests/blackbox/test_tags.py test_tags.py-20070116132048-5h4qak2cm22jlb9e-1
  bzrlib/tests/per_branch/test_tags.py test_tags.py-20070212110545-w2s799hm2jlbsmg5-1
  bzrlib/tests/test_tag.py       test_tag.py-20070212110532-91cw79inah2cfozx-2
=== modified file 'NEWS'
--- a/NEWS	2010-03-22 11:39:16 +0000
+++ b/NEWS	2010-03-22 13:59:33 +0000
@@ -58,6 +58,10 @@
   a list of plugin names separated by ':' (';' on windows).
   (Vincent Ladeuil, #411413)
 
+* Tag names can now be determined automatically by ``automatic_tag_name`` 
+  hooks on ``Branch`` if they are not specified on the command line.
+  (Jelmer Vernooij)
+
 * Tree-shape conflicts can be resolved by providing ``--take-this`` and
   ``--take-other`` to the ``bzr resolve`` command. Just marking the conflict
   as resolved is still accessible via the ``--done`` default action.
@@ -206,6 +210,9 @@
 * ``bzrlib.errors.BoundBranchOutOfDate`` has a new field ``extra_help``
   which can be set to add extra help to the error. (Gary van der Merwe)
 
+* New method ``Branch.automatic_tag_name`` that can be used to find the
+  tag name for a particular revision automatically. (Jelmer Vernooij)
+
 * The methods ``BzrDir.create_branch()``, ``BzrDir.destroy_branch()`` and 
   ``BzrDir.open_branch()`` now take an optional ``name`` argument. 
   (Jelmer Vernooij)

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2010-03-11 14:19:40 +0000
+++ b/bzrlib/branch.py	2010-03-22 13:59:33 +0000
@@ -1366,6 +1366,18 @@
     def supports_tags(self):
         return self._format.supports_tags()
 
+    def automatic_tag_name(self, revision_id):
+        """Try to automatically find the tag name for a revision.
+
+        :param revision_id: Revision id of the revision.
+        :return: A tag name or None if no tag name could be determined.
+        """
+        for hook in Branch.hooks['automatic_tag_name']:
+            ret = hook(self, revision_id)
+            if ret is not None:
+                return ret
+        return None
+
     def _check_if_descendant_or_diverged(self, revision_a, revision_b, graph,
                                          other_branch):
         """Ensure that revision_b is a descendant of revision_a.
@@ -1685,6 +1697,13 @@
             "multiple hooks installed for transform_fallback_location, "
             "all are called with the url returned from the previous hook."
             "The order is however undefined.", (1, 9), None))
+        self.create_hook(HookPoint('automatic_tag_name',
+            "Called to determine an automatic tag name for a revision."
+            "automatic_tag_name is called with (branch, revision_id) and "
+            "should return a tag name or None if no tag name could be "
+            "determined. The first non-None tag name returned will be used.",
+            (2, 2), None))
+
 
 
 # install the default hooks into the Branch class.

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2010-03-22 11:39:16 +0000
+++ b/bzrlib/builtins.py	2010-03-22 13:59:33 +0000
@@ -5268,10 +5268,15 @@
 
     To rename a tag (change the name but keep it on the same revsion), run ``bzr
     tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
+
+    If no tag name is specified it will be determined through the 
+    'automatic_tag_name' hook. This can e.g. be used to automatically tag
+    upstream releases by reading configure.ac. See ``bzr help hooks`` for
+    details.
     """
 
     _see_also = ['commit', 'tags']
-    takes_args = ['tag_name']
+    takes_args = ['tag_name?']
     takes_options = [
         Option('delete',
             help='Delete this tag rather than placing it.',
@@ -5287,7 +5292,7 @@
         'revision',
         ]
 
-    def run(self, tag_name,
+    def run(self, tag_name=None,
             delete=None,
             directory='.',
             force=None,
@@ -5297,6 +5302,8 @@
         branch.lock_write()
         self.add_cleanup(branch.unlock)
         if delete:
+            if tag_name is None:
+                raise errors.BzrCommandError("No tag specified to delete.")
             branch.tags.delete_tag(tag_name)
             self.outf.write('Deleted tag %s.\n' % tag_name)
         else:
@@ -5308,6 +5315,11 @@
                 revision_id = revision[0].as_revision_id(branch)
             else:
                 revision_id = branch.last_revision()
+            if tag_name is None:
+                tag_name = branch.automatic_tag_name(revision_id)
+                if tag_name is None:
+                    raise errors.BzrCommandError(
+                        "Please specify a tag name.")
             if (not force) and branch.tags.has_tag(tag_name):
                 raise errors.TagAlreadyExists(tag_name)
             branch.tags.set_tag(tag_name, revision_id)

=== modified file 'bzrlib/tag.py'
--- a/bzrlib/tag.py	2009-06-10 03:56:49 +0000
+++ b/bzrlib/tag.py	2010-03-12 02:14:56 +0000
@@ -26,8 +26,6 @@
 # called tags* are ctags files... mbp 20070220.
 
 
-from warnings import warn
-
 from bzrlib import (
     bencode,
     errors,
@@ -253,3 +251,4 @@
 
 def _merge_tags_if_possible(from_branch, to_branch):
     from_branch.tags.merge_to(to_branch.tags)
+

=== modified file 'bzrlib/tests/blackbox/test_tags.py'
--- a/bzrlib/tests/blackbox/test_tags.py	2009-08-20 04:09:58 +0000
+++ b/bzrlib/tests/blackbox/test_tags.py	2010-03-12 02:02:31 +0000
@@ -16,7 +16,10 @@
 
 """Tests for commands related to tags"""
 
-from bzrlib import bzrdir
+from bzrlib import (
+    bzrdir,
+    tag,
+    )
 from bzrlib.branch import (
     Branch,
     )
@@ -47,6 +50,18 @@
         self.assertContainsRe(err,
             "Tags can only be placed on a single revision")
 
+    def test_no_tag_name(self):
+        out, err = self.run_bzr('tag -d branch', retcode=3)
+        self.assertContainsRe(err, 'Please specify a tag name.')
+
+    def test_automatic_tag_name(self):
+        def get_tag_name(branch, revid):
+            return "mytag"
+        Branch.hooks.install_named_hook('automatic_tag_name',
+            get_tag_name, 'get tag name')
+        out, err = self.run_bzr('tag -d branch')
+        self.assertContainsRe(out, 'Created tag mytag.')
+
     def test_tag_current_rev(self):
         t = self.make_branch_and_tree('branch')
         t.commit(allow_pointless=True, message='initial commit',
@@ -73,6 +88,10 @@
         # ... but can if you use --force
         out, err = self.run_bzr('tag -d branch NEWTAG --force')
 
+    def test_tag_delete_requires_name(self):
+        out, err = self.run_bzr('tag -d branch', retcode=3)
+        self.assertContainsRe(err, 'Please specify a tag name\\.')
+
     def test_branch_push_pull_merge_copies_tags(self):
         t = self.make_branch_and_tree('branch1')
         t.commit(allow_pointless=True, message='initial commit',

=== modified file 'bzrlib/tests/per_branch/test_tags.py'
--- a/bzrlib/tests/per_branch/test_tags.py	2010-02-10 17:52:08 +0000
+++ b/bzrlib/tests/per_branch/test_tags.py	2010-03-12 02:14:56 +0000
@@ -171,3 +171,54 @@
         b1 = self.make_branch('b1')
         b2 = self.make_branch('b2')
         b1.tags.merge_to(b2.tags)
+
+
+class AutomaticTagNameTests(per_branch.TestCaseWithBranch):
+
+    def setUp(self):
+        super(AutomaticTagNameTests, self).setUp()
+        if isinstance(self.branch_format, branch.BranchReferenceFormat):
+            # This test could in principle apply to BranchReferenceFormat, but
+            # make_branch_builder doesn't support it.
+            raise tests.TestSkipped(
+                "BranchBuilder can't make reference branches.")
+        self.builder = self.make_branch_builder('.')
+        self.builder.build_snapshot('foo', None,
+            [('add', ('', None, 'directory', None))],
+            message='foo')
+        self.branch = self.builder.get_branch()
+        if not self.branch._format.supports_tags():
+            raise tests.TestSkipped(
+                "format %s doesn't support tags" % self.branch._format)
+
+    def test_no_functions(self):
+        rev = self.branch.last_revision()
+        self.assertEquals(None, self.branch.automatic_tag_name(rev))
+
+    def test_returns_tag_name(self):
+        def get_tag_name(br, revid):
+            return "foo"
+        branch.Branch.hooks.install_named_hook('automatic_tag_name',
+            get_tag_name, 'get tag name foo')
+        self.assertEquals("foo", self.branch.automatic_tag_name(
+            self.branch.last_revision()))
+    
+    def test_uses_first_return(self):
+        get_tag_name_1 = lambda br, revid: "foo1"
+        get_tag_name_2 = lambda br, revid: "foo2"
+        branch.Branch.hooks.install_named_hook('automatic_tag_name',
+            get_tag_name_1, 'tagname1')
+        branch.Branch.hooks.install_named_hook('automatic_tag_name',
+            get_tag_name_2, 'tagname2')
+        self.assertEquals("foo1", self.branch.automatic_tag_name(
+            self.branch.last_revision()))
+
+    def test_ignores_none(self):
+        get_tag_name_1 = lambda br, revid: None
+        get_tag_name_2 = lambda br, revid: "foo2"
+        branch.Branch.hooks.install_named_hook('automatic_tag_name',
+            get_tag_name_1, 'tagname1')
+        branch.Branch.hooks.install_named_hook('automatic_tag_name',
+            get_tag_name_2, 'tagname2')
+        self.assertEquals("foo2", self.branch.automatic_tag_name(
+            self.branch.last_revision()))

=== modified file 'bzrlib/tests/test_tag.py'
--- a/bzrlib/tests/test_tag.py	2009-05-06 05:36:28 +0000
+++ b/bzrlib/tests/test_tag.py	2010-03-22 12:06:58 +0000
@@ -14,16 +14,15 @@
 # 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 bzrlib.tag."""
+
 
 from bzrlib import (
-    branch,
     bzrdir,
     errors,
-    tag,
     )
 from bzrlib.tag import (
     BasicTags,
-    _merge_tags_if_possible,
     DisabledTags,
     )
 from bzrlib.tests import (
@@ -184,3 +183,6 @@
 
     def test_get_reverse_tag_dict(self):
         self.assertEqual(self.tags.get_reverse_tag_dict(), {})
+
+
+




More information about the bazaar-commits mailing list