~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commit_signature_commands.py

  • Committer: Kit Randel
  • Date: 2014-12-15 20:24:42 UTC
  • mto: This revision was merged to the branch mainline in revision 6602.
  • Revision ID: kit.randel@canonical.com-20141215202442-usf2ixhypqg8yh6q
added a note for bug-1400567 to the 2.7b release notes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2006, 2007, 2009, 2010, 2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Command which looks for unsigned commits by the current user, and signs them.
18
18
"""
19
19
 
20
 
from bzrlib.lazy_import import lazy_import
21
 
lazy_import(globals(), """
 
20
from __future__ import absolute_import
 
21
 
22
22
from bzrlib import (
23
 
    config,
 
23
    controldir,
 
24
    errors,
24
25
    gpg,
 
26
    revision as _mod_revision,
25
27
    )
26
 
from bzrlib.bzrdir import BzrDir
27
 
""")
28
28
from bzrlib.commands import Command
29
29
from bzrlib.option import Option
 
30
from bzrlib.i18n import gettext, ngettext
30
31
 
31
32
 
32
33
class cmd_sign_my_commits(Command):
50
51
 
51
52
    def run(self, location=None, committer=None, dry_run=False):
52
53
        if location is None:
53
 
            bzrdir = BzrDir.open_containing('.')[0]
 
54
            bzrdir = controldir.ControlDir.open_containing('.')[0]
54
55
        else:
55
56
            # Passed in locations should be exact
56
 
            bzrdir = BzrDir.open(location)
 
57
            bzrdir = controldir.ControlDir.open(location)
57
58
        branch = bzrdir.open_branch()
58
59
        repo = branch.repository
59
 
        branch_config = branch.get_config()
 
60
        branch_config = branch.get_config_stack()
60
61
 
61
62
        if committer is None:
62
 
            committer = branch_config.username()
 
63
            committer = branch_config.get('email')
63
64
        gpg_strategy = gpg.GPGStrategy(branch_config)
64
65
 
65
66
        count = 0
66
67
        repo.lock_write()
67
68
        try:
 
69
            graph = repo.get_graph()
68
70
            repo.start_write_group()
69
71
            try:
70
 
                for rev_id in repo.get_ancestry(branch.last_revision())[1:]:
 
72
                for rev_id, parents in graph.iter_ancestry(
 
73
                        [branch.last_revision()]):
 
74
                    if _mod_revision.is_null(rev_id):
 
75
                        continue
 
76
                    if parents is None:
 
77
                        # Ignore ghosts
 
78
                        continue
71
79
                    if repo.has_signature_for_revision_id(rev_id):
72
80
                        continue
73
81
                    rev = repo.get_revision(rev_id)
75
83
                        continue
76
84
                    # We have a revision without a signature who has a
77
85
                    # matching committer, start signing
78
 
                    print rev_id
 
86
                    self.outf.write("%s\n" % rev_id)
79
87
                    count += 1
80
88
                    if not dry_run:
81
89
                        repo.sign_revision(rev_id, gpg_strategy)
86
94
                repo.commit_write_group()
87
95
        finally:
88
96
            repo.unlock()
89
 
        print 'Signed %d revisions' % (count,)
90
 
 
91
 
 
 
97
        self.outf.write(
 
98
            ngettext('Signed %d revision.\n', 'Signed %d revisions.\n', count) %
 
99
            count)
 
100
 
 
101
 
 
102
class cmd_verify_signatures(Command):
 
103
    __doc__ = """Verify all commit signatures.
 
104
 
 
105
    Verifies that all commits in the branch are signed by known GnuPG keys.
 
106
    """
 
107
 
 
108
    takes_options = [
 
109
            Option('acceptable-keys',
 
110
                   help='Comma separated list of GPG key patterns which are'
 
111
                        ' acceptable for verification.',
 
112
                   short_name='k',
 
113
                   type=str,),
 
114
            'revision',
 
115
            'verbose',
 
116
          ]
 
117
    takes_args = ['location?']
 
118
 
 
119
    def run(self, acceptable_keys=None, revision=None, verbose=None,
 
120
                                                            location=u'.'):
 
121
        bzrdir = controldir.ControlDir.open_containing(location)[0]
 
122
        branch = bzrdir.open_branch()
 
123
        repo = branch.repository
 
124
        branch_config = branch.get_config_stack()
 
125
        gpg_strategy = gpg.GPGStrategy(branch_config)
 
126
 
 
127
        gpg_strategy.set_acceptable_keys(acceptable_keys)
 
128
 
 
129
        def write(string):
 
130
            self.outf.write(string + "\n")
 
131
        def write_verbose(string):
 
132
            self.outf.write("  " + string + "\n")
 
133
 
 
134
        self.add_cleanup(repo.lock_read().unlock)
 
135
        #get our list of revisions
 
136
        revisions = []
 
137
        if revision is not None:
 
138
            if len(revision) == 1:
 
139
                revno, rev_id = revision[0].in_history(branch)
 
140
                revisions.append(rev_id)
 
141
            elif len(revision) == 2:
 
142
                from_revno, from_revid = revision[0].in_history(branch)
 
143
                to_revno, to_revid = revision[1].in_history(branch)
 
144
                if to_revid is None:
 
145
                    to_revno = branch.revno()
 
146
                if from_revno is None or to_revno is None:
 
147
                    raise errors.BzrCommandError(gettext(
 
148
                    'Cannot verify a range of non-revision-history revisions'))
 
149
                for revno in range(from_revno, to_revno + 1):
 
150
                    revisions.append(branch.get_rev_id(revno))
 
151
        else:
 
152
            #all revisions by default including merges
 
153
            graph = repo.get_graph()
 
154
            revisions = []
 
155
            for rev_id, parents in graph.iter_ancestry(
 
156
                    [branch.last_revision()]):
 
157
                if _mod_revision.is_null(rev_id):
 
158
                    continue
 
159
                if parents is None:
 
160
                    # Ignore ghosts
 
161
                    continue
 
162
                revisions.append(rev_id)
 
163
        count, result, all_verifiable = gpg.bulk_verify_signatures(
 
164
            repo, revisions, gpg_strategy)
 
165
        if all_verifiable:
 
166
               write(gettext("All commits signed with verifiable keys"))
 
167
               if verbose:
 
168
                   for message in gpg.verbose_valid_message(result):
 
169
                       write_verbose(message)
 
170
               return 0
 
171
        else:
 
172
            write(gpg.valid_commits_message(count))
 
173
            if verbose:
 
174
               for message in gpg.verbose_valid_message(result):
 
175
                   write_verbose(message)
 
176
            write(gpg.expired_commit_message(count))
 
177
            if verbose:
 
178
               for message in gpg.verbose_expired_key_message(result, repo):
 
179
                   write_verbose(message)
 
180
            write(gpg.unknown_key_message(count))
 
181
            if verbose:
 
182
                for message in gpg.verbose_missing_key_message(result):
 
183
                    write_verbose(message)
 
184
            write(gpg.commit_not_valid_message(count))
 
185
            if verbose:
 
186
                for message in gpg.verbose_not_valid_message(result, repo):
 
187
                   write_verbose(message)
 
188
            write(gpg.commit_not_signed_message(count))
 
189
            if verbose:
 
190
                for message in gpg.verbose_not_signed_message(result, repo):
 
191
                    write_verbose(message)
 
192
            return 1