Rev 6494: (jelmer) Various fixes for 'bzr verify-signatures'. (Jelmer Vernooij) in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

Patch Queue Manager pqm at pqm.ubuntu.com
Mon Mar 12 12:36:00 UTC 2012


At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 6494 [merge]
revision-id: pqm at pqm.ubuntu.com-20120312123559-g4tqzz3790kszu03
parent: pqm at pqm.ubuntu.com-20120312104412-vm46n41e9kr4xf27
parent: jelmer at samba.org-20120311170617-6edlhqlh2scqxfr3
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2012-03-12 12:35:59 +0000
message:
  (jelmer) Various fixes for 'bzr verify-signatures'. (Jelmer Vernooij)
modified:
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/commit_signature_commands.py sign_my_commits.py-20060215152201-5a6363365180e671
  bzrlib/gpg.py                  gpg.py-20051017065112-8654536d415dacc6
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/blackbox/test_sign_my_commits.py test_sign_my_commits.py-20060215152957-270238a1ffacc841
  bzrlib/tests/per_repository/test_signatures.py test_signatures.py-20111010140248-mdiotjn81vw9p7yb-1
  doc/en/release-notes/bzr-2.6.txt bzr2.6.txt-20120116134316-8w1xxom1c7vcu1t5-1
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2012-03-09 14:16:52 +0000
+++ b/bzrlib/builtins.py	2012-03-11 15:47:27 +0000
@@ -6692,8 +6692,7 @@
         ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
         ('cmd_conflicts', [], 'bzrlib.conflicts'),
         ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
-        ('cmd_verify_signatures', [],
-                                        'bzrlib.commit_signature_commands'),
+        ('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
         ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
         ]:
         builtin_command_registry.register_lazy(name, aliases, module_name)

=== modified file 'bzrlib/commit_signature_commands.py'
--- a/bzrlib/commit_signature_commands.py	2012-01-28 17:36:39 +0000
+++ b/bzrlib/commit_signature_commands.py	2012-03-11 16:51:49 +0000
@@ -19,19 +19,17 @@
 
 from __future__ import absolute_import
 
-from bzrlib.lazy_import import lazy_import
-lazy_import(globals(), """
 from bzrlib import (
     controldir,
     errors,
     gpg,
     revision as _mod_revision,
     )
-""")
 from bzrlib.commands import Command
 from bzrlib.option import Option
 from bzrlib.i18n import gettext, ngettext
 
+
 class cmd_sign_my_commits(Command):
     __doc__ = """Sign all commits by a given committer.
 
@@ -85,7 +83,7 @@
                         continue
                     # We have a revision without a signature who has a
                     # matching committer, start signing
-                    print rev_id
+                    self.outf.write("%s\n" % rev_id)
                     count += 1
                     if not dry_run:
                         repo.sign_revision(rev_id, gpg_strategy)
@@ -96,7 +94,9 @@
                 repo.commit_write_group()
         finally:
             repo.unlock()
-        print 'Signed %d revisions' % (count,)
+        self.outf.write(
+            ngettext('Signed %d revision.\n', 'Signed %d revisions.\n', count) %
+            count)
 
 
 class cmd_verify_signatures(Command):
@@ -131,6 +131,7 @@
         def write_verbose(string):
             self.outf.write("  " + string + "\n")
 
+        self.add_cleanup(repo.lock_read().unlock)
         #get our list of revisions
         revisions = []
         if revision is not None:
@@ -151,7 +152,6 @@
             #all revisions by default including merges
             graph = repo.get_graph()
             revisions = []
-            repo.lock_read()
             for rev_id, parents in graph.iter_ancestry(
                     [branch.last_revision()]):
                 if _mod_revision.is_null(rev_id):
@@ -160,37 +160,32 @@
                     # Ignore ghosts
                     continue
                 revisions.append(rev_id)
-            repo.unlock()
         count, result, all_verifiable =\
-                                gpg_strategy.do_verifications(revisions, repo)
+                                gpg.bulk_verify_signatures(repo, revisions, gpg_strategy)
         if all_verifiable:
-               write(gettext(
-                            "All commits signed with verifiable keys"))
+               write(gettext("All commits signed with verifiable keys"))
                if verbose:
-                   write(gpg_strategy.verbose_valid_message(result))
+                   write(gpg.verbose_valid_message(result))
                return 0
         else:
-            write(gpg_strategy.valid_commits_message(count))
-            if verbose:
-               for message in gpg_strategy.verbose_valid_message(result):
-                   write_verbose(message)
-            write(gpg_strategy.expired_commit_message(count))
-            if verbose:
-               for message in gpg_strategy.verbose_expired_key_message(result,
-                                                                          repo):
-                   write_verbose(message)
-            write(gpg_strategy.unknown_key_message(count))
-            if verbose:
-                for message in gpg_strategy.verbose_missing_key_message(result):
+            write(gpg.valid_commits_message(count))
+            if verbose:
+               for message in gpg.verbose_valid_message(result):
+                   write_verbose(message)
+            write(gpg.expired_commit_message(count))
+            if verbose:
+               for message in gpg.verbose_expired_key_message(result, repo):
+                   write_verbose(message)
+            write(gpg.unknown_key_message(count))
+            if verbose:
+                for message in gpg.verbose_missing_key_message(result):
                     write_verbose(message)
-            write(gpg_strategy.commit_not_valid_message(count))
+            write(gpg.commit_not_valid_message(count))
             if verbose:
-                for message in gpg_strategy.verbose_not_valid_message(result,
-                                                                        repo):
+                for message in gpg.verbose_not_valid_message(result, repo):
                    write_verbose(message)
-            write(gpg_strategy.commit_not_signed_message(count))
+            write(gpg.commit_not_signed_message(count))
             if verbose:
-                for message in gpg_strategy.verbose_not_signed_message(result,
-                                                                          repo):
+                for message in gpg.verbose_not_signed_message(result, repo):
                     write_verbose(message)
             return 1

=== modified file 'bzrlib/gpg.py'
--- a/bzrlib/gpg.py	2012-02-27 20:16:25 +0000
+++ b/bzrlib/gpg.py	2012-03-12 12:35:59 +0000
@@ -40,6 +40,11 @@
     )
 """)
 
+from bzrlib.symbol_versioning import (
+    deprecated_in,
+    deprecated_method,
+    )
+
 #verification results
 SIGNATURE_VALID = 0
 SIGNATURE_KEY_MISSING = 1
@@ -48,6 +53,45 @@
 SIGNATURE_EXPIRED = 4
 
 
+def bulk_verify_signatures(repository, revids, strategy,
+        process_events_callback=None):
+    """Do verifications on a set of revisions
+
+    :param repository: repository object
+    :param revids: list of revision ids to verify
+    :param strategy: GPG strategy to use
+    :param process_events_callback: method to call for GUI frontends that
+        want to keep their UI refreshed
+
+    :return: count dictionary of results of each type,
+             result list for each revision,
+             boolean True if all results are verified successfully
+    """
+    count = {SIGNATURE_VALID: 0,
+             SIGNATURE_KEY_MISSING: 0,
+             SIGNATURE_NOT_VALID: 0,
+             SIGNATURE_NOT_SIGNED: 0,
+             SIGNATURE_EXPIRED: 0}
+    result = []
+    all_verifiable = True
+    total = len(revids)
+    pb = ui.ui_factory.nested_progress_bar()
+    try:
+        for i, (rev_id, verification_result, uid) in enumerate(
+                repository.verify_revision_signatures(
+                    revids, strategy)):
+            pb.update("verifying signatures", i, total)
+            result.append([rev_id, verification_result, uid])
+            count[verification_result] += 1
+            if verification_result != SIGNATURE_VALID:
+                all_verifiable = False
+            if process_events_callback is not None:
+                process_events_callback()
+    finally:
+        pb.finished()
+    return (count, result, all_verifiable)
+
+
 class DisabledGPGStrategy(object):
     """A GPG Strategy that makes everything fail."""
 
@@ -98,50 +142,29 @@
                 else:
                     self.acceptable_keys.append(pattern)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def do_verifications(self, revisions, repository):
-        count = {SIGNATURE_VALID: 0,
-                 SIGNATURE_KEY_MISSING: 0,
-                 SIGNATURE_NOT_VALID: 0,
-                 SIGNATURE_NOT_SIGNED: 0,
-                 SIGNATURE_EXPIRED: 0}
-        result = []
-        all_verifiable = True
-        for rev_id in revisions:
-            verification_result, uid =\
-                repository.verify_revision_signature(rev_id,self)
-            result.append([rev_id, verification_result, uid])
-            count[verification_result] += 1
-            if verification_result != SIGNATURE_VALID:
-                all_verifiable = False
-        return (count, result, all_verifiable)
+        return bulk_verify_signatures(repository, revisions, self)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def valid_commits_message(self, count):
-        return gettext(u"{0} commits with valid signatures").format(
-                                        count[SIGNATURE_VALID])
+        return valid_commits_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def unknown_key_message(self, count):
-        return ngettext(u"{0} commit with unknown key",
-                             u"{0} commits with unknown keys",
-                             count[SIGNATURE_KEY_MISSING]).format(
-                                        count[SIGNATURE_KEY_MISSING])
+        return unknown_key_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def commit_not_valid_message(self, count):
-        return ngettext(u"{0} commit not valid",
-                             u"{0} commits not valid",
-                             count[SIGNATURE_NOT_VALID]).format(
-                                            count[SIGNATURE_NOT_VALID])
+        return commit_not_valid_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def commit_not_signed_message(self, count):
-        return ngettext(u"{0} commit not signed",
-                             u"{0} commits not signed",
-                             count[SIGNATURE_NOT_SIGNED]).format(
-                                        count[SIGNATURE_NOT_SIGNED])
+        return commit_not_signed_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def expired_commit_message(self, count):
-        return ngettext(u"{0} commit with key now expired",
-                        u"{0} commits with key now expired",
-                        count[SIGNATURE_EXPIRED]).format(
-                                        count[SIGNATURE_EXPIRED])
+        return expired_commit_message(count)
 
 
 def _set_gpg_tty():
@@ -230,10 +253,10 @@
 
     def verify(self, content, testament):
         """Check content has a valid signature.
-        
+
         :param content: the commit signature
         :param testament: the valid testament string for the commit
-        
+
         :return: SIGNATURE_VALID or a failed SIGNATURE_ value, key uid if valid
         """
         try:
@@ -308,7 +331,7 @@
 
     def set_acceptable_keys(self, command_line_input):
         """Set the acceptable keys for verifying with this GPGStrategy.
-        
+
         :param command_line_input: comma separated list of patterns from
                                 command line
         :return: nothing
@@ -343,147 +366,192 @@
                             "No GnuPG key results for pattern: {0}"
                                 ).format(pattern))
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def do_verifications(self, revisions, repository,
                             process_events_callback=None):
         """do verifications on a set of revisions
-        
+
         :param revisions: list of revision ids to verify
         :param repository: repository object
         :param process_events_callback: method to call for GUI frontends that
-                                                want to keep their UI refreshed
-        
+            want to keep their UI refreshed
+
         :return: count dictionary of results of each type,
                  result list for each revision,
                  boolean True if all results are verified successfully
         """
-        count = {SIGNATURE_VALID: 0,
-                 SIGNATURE_KEY_MISSING: 0,
-                 SIGNATURE_NOT_VALID: 0,
-                 SIGNATURE_NOT_SIGNED: 0,
-                 SIGNATURE_EXPIRED: 0}
-        result = []
-        all_verifiable = True
-        for rev_id in revisions:
-            verification_result, uid =\
-                repository.verify_revision_signature(rev_id, self)
-            result.append([rev_id, verification_result, uid])
-            count[verification_result] += 1
-            if verification_result != SIGNATURE_VALID:
-                all_verifiable = False
-            if process_events_callback is not None:
-                process_events_callback()
-        return (count, result, all_verifiable)
+        return bulk_verify_signatures(repository, revisions, self,
+            process_events_callback)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def verbose_valid_message(self, result):
         """takes a verify result and returns list of signed commits strings"""
-        signers = {}
-        for rev_id, validity, uid in result:
-            if validity == SIGNATURE_VALID:
-                signers.setdefault(uid, 0)
-                signers[uid] += 1
-        result = []
-        for uid, number in signers.items():
-             result.append( ngettext(u"{0} signed {1} commit",
-                             u"{0} signed {1} commits",
-                             number).format(uid, number) )
-        return result
-
-
+        return verbose_valid_message(result)
+
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def verbose_not_valid_message(self, result, repo):
         """takes a verify result and returns list of not valid commit info"""
-        signers = {}
-        for rev_id, validity, empty in result:
-            if validity == SIGNATURE_NOT_VALID:
-                revision = repo.get_revision(rev_id)
-                authors = ', '.join(revision.get_apparent_authors())
-                signers.setdefault(authors, 0)
-                signers[authors] += 1
-        result = []
-        for authors, number in signers.items():
-            result.append( ngettext(u"{0} commit by author {1}",
-                                 u"{0} commits by author {1}",
-                                 number).format(number, authors) )
-        return result
+        return verbose_not_valid_message(result, repo)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def verbose_not_signed_message(self, result, repo):
         """takes a verify result and returns list of not signed commit info"""
-        signers = {}
-        for rev_id, validity, empty in result:
-            if validity == SIGNATURE_NOT_SIGNED:
-                revision = repo.get_revision(rev_id)
-                authors = ', '.join(revision.get_apparent_authors())
-                signers.setdefault(authors, 0)
-                signers[authors] += 1
-        result = []
-        for authors, number in signers.items():
-            result.append( ngettext(u"{0} commit by author {1}",
-                                 u"{0} commits by author {1}",
-                                 number).format(number, authors) )
-        return result
+        return verbose_not_valid_message(result, repo)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def verbose_missing_key_message(self, result):
         """takes a verify result and returns list of missing key info"""
-        signers = {}
-        for rev_id, validity, fingerprint in result:
-            if validity == SIGNATURE_KEY_MISSING:
-                signers.setdefault(fingerprint, 0)
-                signers[fingerprint] += 1
-        result = []
-        for fingerprint, number in signers.items():
-            result.append( ngettext(u"Unknown key {0} signed {1} commit",
-                                 u"Unknown key {0} signed {1} commits",
-                                 number).format(fingerprint, number) )
-        return result
+        return verbose_missing_key_message(result)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def verbose_expired_key_message(self, result, repo):
         """takes a verify result and returns list of expired key info"""
-        signers = {}
-        fingerprint_to_authors = {}
-        for rev_id, validity, fingerprint in result:
-            if validity == SIGNATURE_EXPIRED:
-                revision = repo.get_revision(rev_id)
-                authors = ', '.join(revision.get_apparent_authors())
-                signers.setdefault(fingerprint, 0)
-                signers[fingerprint] += 1
-                fingerprint_to_authors[fingerprint] = authors
-        result = []
-        for fingerprint, number in signers.items():
-            result.append(
-                ngettext(u"{0} commit by author {1} with key {2} now expired",
-                         u"{0} commits by author {1} with key {2} now expired",
-                         number).format(
-                    number, fingerprint_to_authors[fingerprint], fingerprint) )
-        return result
+        return verbose_expired_key_message(result, repo)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def valid_commits_message(self, count):
         """returns message for number of commits"""
-        return gettext(u"{0} commits with valid signatures").format(
-                                        count[SIGNATURE_VALID])
+        return valid_commits_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def unknown_key_message(self, count):
         """returns message for number of commits"""
-        return ngettext(u"{0} commit with unknown key",
-                        u"{0} commits with unknown keys",
-                        count[SIGNATURE_KEY_MISSING]).format(
-                                        count[SIGNATURE_KEY_MISSING])
+        return unknown_key_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def commit_not_valid_message(self, count):
         """returns message for number of commits"""
-        return ngettext(u"{0} commit not valid",
-                        u"{0} commits not valid",
-                        count[SIGNATURE_NOT_VALID]).format(
-                                            count[SIGNATURE_NOT_VALID])
+        return commit_not_valid_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def commit_not_signed_message(self, count):
         """returns message for number of commits"""
-        return ngettext(u"{0} commit not signed",
-                        u"{0} commits not signed",
-                        count[SIGNATURE_NOT_SIGNED]).format(
-                                        count[SIGNATURE_NOT_SIGNED])
+        return commit_not_signed_message(count)
 
+    @deprecated_method(deprecated_in((2, 6, 0)))
     def expired_commit_message(self, count):
         """returns message for number of commits"""
-        return ngettext(u"{0} commit with key now expired",
-                        u"{0} commits with key now expired",
-                        count[SIGNATURE_EXPIRED]).format(
-                                    count[SIGNATURE_EXPIRED])
+        return expired_commit_message(count)
+
+
+def valid_commits_message(count):
+    """returns message for number of commits"""
+    return gettext(u"{0} commits with valid signatures").format(
+                                    count[SIGNATURE_VALID])
+
+
+def unknown_key_message(count):
+    """returns message for number of commits"""
+    return ngettext(u"{0} commit with unknown key",
+                    u"{0} commits with unknown keys",
+                    count[SIGNATURE_KEY_MISSING]).format(
+                                    count[SIGNATURE_KEY_MISSING])
+
+
+def commit_not_valid_message(count):
+    """returns message for number of commits"""
+    return ngettext(u"{0} commit not valid",
+                    u"{0} commits not valid",
+                    count[SIGNATURE_NOT_VALID]).format(
+                                        count[SIGNATURE_NOT_VALID])
+
+
+def commit_not_signed_message(count):
+    """returns message for number of commits"""
+    return ngettext(u"{0} commit not signed",
+                    u"{0} commits not signed",
+                    count[SIGNATURE_NOT_SIGNED]).format(
+                                    count[SIGNATURE_NOT_SIGNED])
+
+
+def expired_commit_message(count):
+    """returns message for number of commits"""
+    return ngettext(u"{0} commit with key now expired",
+                    u"{0} commits with key now expired",
+                    count[SIGNATURE_EXPIRED]).format(
+                                count[SIGNATURE_EXPIRED])
+
+
+def verbose_expired_key_message(result, repo):
+    """takes a verify result and returns list of expired key info"""
+    signers = {}
+    fingerprint_to_authors = {}
+    for rev_id, validity, fingerprint in result:
+        if validity == SIGNATURE_EXPIRED:
+            revision = repo.get_revision(rev_id)
+            authors = ', '.join(revision.get_apparent_authors())
+            signers.setdefault(fingerprint, 0)
+            signers[fingerprint] += 1
+            fingerprint_to_authors[fingerprint] = authors
+    result = []
+    for fingerprint, number in signers.items():
+        result.append(
+            ngettext(u"{0} commit by author {1} with key {2} now expired",
+                     u"{0} commits by author {1} with key {2} now expired",
+                     number).format(
+                number, fingerprint_to_authors[fingerprint], fingerprint))
+    return result
+
+
+def verbose_valid_message(result):
+    """takes a verify result and returns list of signed commits strings"""
+    signers = {}
+    for rev_id, validity, uid in result:
+        if validity == SIGNATURE_VALID:
+            signers.setdefault(uid, 0)
+            signers[uid] += 1
+    result = []
+    for uid, number in signers.items():
+         result.append(ngettext(u"{0} signed {1} commit",
+                                u"{0} signed {1} commits",
+                                number).format(uid, number))
+    return result
+
+
+def verbose_not_valid_message(result, repo):
+    """takes a verify result and returns list of not valid commit info"""
+    signers = {}
+    for rev_id, validity, empty in result:
+        if validity == SIGNATURE_NOT_VALID:
+            revision = repo.get_revision(rev_id)
+            authors = ', '.join(revision.get_apparent_authors())
+            signers.setdefault(authors, 0)
+            signers[authors] += 1
+    result = []
+    for authors, number in signers.items():
+        result.append(ngettext(u"{0} commit by author {1}",
+                               u"{0} commits by author {1}",
+                               number).format(number, authors))
+    return result
+
+
+def verbose_not_signed_message(result, repo):
+    """takes a verify result and returns list of not signed commit info"""
+    signers = {}
+    for rev_id, validity, empty in result:
+        if validity == SIGNATURE_NOT_SIGNED:
+            revision = repo.get_revision(rev_id)
+            authors = ', '.join(revision.get_apparent_authors())
+            signers.setdefault(authors, 0)
+            signers[authors] += 1
+    result = []
+    for authors, number in signers.items():
+        result.append(ngettext(u"{0} commit by author {1}",
+                               u"{0} commits by author {1}",
+                               number).format(number, authors))
+    return result
+
+
+def verbose_missing_key_message(result):
+    """takes a verify result and returns list of missing key info"""
+    signers = {}
+    for rev_id, validity, fingerprint in result:
+        if validity == SIGNATURE_KEY_MISSING:
+            signers.setdefault(fingerprint, 0)
+            signers[fingerprint] += 1
+    result = []
+    for fingerprint, number in signers.items():
+        result.append(ngettext(u"Unknown key {0} signed {1} commit",
+                               u"Unknown key {0} signed {1} commits",
+                               number).format(fingerprint, number))
+    return result

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2012-01-27 21:59:34 +0000
+++ b/bzrlib/repository.py	2012-03-11 17:03:05 +0000
@@ -1174,10 +1174,10 @@
     @needs_read_lock
     def verify_revision_signature(self, revision_id, gpg_strategy):
         """Verify the signature on a revision.
-        
+
         :param revision_id: the revision to verify
         :gpg_strategy: the GPGStrategy object to used
-        
+
         :return: gpg.SIGNATURE_VALID or a failed SIGNATURE_ value
         """
         if not self.has_signature_for_revision_id(revision_id):
@@ -1189,6 +1189,18 @@
 
         return gpg_strategy.verify(signature, plaintext)
 
+    @needs_read_lock
+    def verify_revision_signatures(self, revision_ids, gpg_strategy):
+        """Verify revision signatures for a number of revisions.
+
+        :param revision_id: the revision to verify
+        :gpg_strategy: the GPGStrategy object to used
+        :return: Iterator over tuples with revision id, result and keys
+        """
+        for revid in revision_ids:
+            (result, key) = self.verify_revision_signature(revid, gpg_strategy)
+            yield revid, result, key
+
     def has_signature_for_revision_id(self, revision_id):
         """Query for a revision signature for revision_id in the repository."""
         raise NotImplementedError(self.has_signature_for_revision_id)

=== modified file 'bzrlib/tests/blackbox/test_sign_my_commits.py'
--- a/bzrlib/tests/blackbox/test_sign_my_commits.py	2011-12-14 21:57:37 +0000
+++ b/bzrlib/tests/blackbox/test_sign_my_commits.py	2012-03-11 16:51:49 +0000
@@ -109,7 +109,7 @@
 
         outlines = out.splitlines()
         self.assertEquals(5, len(outlines))
-        self.assertEquals('Signed 4 revisions', outlines[-1])
+        self.assertEquals('Signed 4 revisions.', outlines[-1])
         self.assertUnsigned(repo, 'A')
         self.assertUnsigned(repo, 'B')
         self.assertUnsigned(repo, 'C')

=== modified file 'bzrlib/tests/per_repository/test_signatures.py'
--- a/bzrlib/tests/per_repository/test_signatures.py	2011-11-15 17:22:02 +0000
+++ b/bzrlib/tests/per_repository/test_signatures.py	2012-03-11 17:06:17 +0000
@@ -126,6 +126,26 @@
             (gpg.SIGNATURE_VALID, None, ),
             repo.verify_revision_signature('A', strategy))
 
+    def test_verify_revision_signatures(self):
+        wt = self.make_branch_and_tree('.')
+        wt.commit("base", allow_pointless=True, rev_id='A')
+        wt.commit("second", allow_pointless=True, rev_id='B')
+        strategy = gpg.LoopbackGPGStrategy(None)
+        repo = wt.branch.repository
+        self.addCleanup(repo.lock_write().unlock)
+        repo.start_write_group()
+        repo.sign_revision('A', strategy)
+        repo.commit_write_group()
+        self.assertEqual('-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
+                         Testament.from_revision(repo,
+                         'A').as_short_text() +
+                         '-----END PSEUDO-SIGNED CONTENT-----\n',
+                         repo.get_signature_text('A'))
+        self.assertEquals(
+            [('A', gpg.SIGNATURE_VALID, None),
+             ('B', gpg.SIGNATURE_NOT_SIGNED, None)],
+            list(repo.verify_revision_signatures(['A', 'B'], strategy)))
+
 
 class TestUnsupportedSignatures(per_repository.TestCaseWithRepository):
 

=== modified file 'doc/en/release-notes/bzr-2.6.txt'
--- a/doc/en/release-notes/bzr-2.6.txt	2012-03-08 18:31:10 +0000
+++ b/doc/en/release-notes/bzr-2.6.txt	2012-03-11 17:03:05 +0000
@@ -43,6 +43,9 @@
 * ``bzr rmbranch`` no longer removes active branches unless ``--force``
   is specified. (Jelmer Vernooij, #922953)
 
+* ``bzr verify-signatures`` now shows a progress bar.
+  (Jelmer Vernooij)
+
 * Two new command hooks, ``pre_command`` and ``post_command``,
   provide notification before and after a command has been run.
   (Brian de Alwis, Jelmer Vernooij)
@@ -67,6 +70,9 @@
 .. Changes that may require updates in plugins or other code that uses
    bzrlib.
 
+* ``GPGStrategy.do_verifications`` has been deprecated.
+  (Jelmer Vernooij)
+
 * File ids in the ``Tree`` API can now be bytestring as previously,
   or tuples of bytestrings.
   (Jelmer Vernooij)
@@ -74,6 +80,9 @@
 * ``mail_client`` now accepts a configuration stack object rather than
   an old style Config object. (Jelmer Vernooij)
 
+* New method ``Repository.verify_revision_signatures``.
+  (Jelmer Vernooij)
+
 * New configuration option class ``RegistryOption`` which is backed
   onto a registry. (Jelmer Vernooij)
 




More information about the bazaar-commits mailing list