/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/commit_signature_commands.py

  • Committer: Martin
  • Date: 2018-11-16 19:10:17 UTC
  • mto: This revision was merged to the branch mainline in revision 7177.
  • Revision ID: gzlist@googlemail.com-20181116191017-kyedz1qck0ovon3h
Remove lazy_regexp reset in bt.test_source

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006, 2007, 2009, 2010, 2011 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Command that signs unsigned commits by the current user. """
 
18
 
 
19
from __future__ import absolute_import
 
20
 
 
21
from . import (
 
22
    controldir,
 
23
    errors,
 
24
    gpg,
 
25
    revision as _mod_revision,
 
26
    )
 
27
from .commands import Command
 
28
from .option import Option
 
29
from .i18n import gettext, ngettext
 
30
from .sixish import text_type
 
31
 
 
32
 
 
33
class cmd_sign_my_commits(Command):
 
34
    __doc__ = """Sign all commits by a given committer.
 
35
 
 
36
    If location is not specified the local tree is used.
 
37
    If committer is not specified the default committer is used.
 
38
 
 
39
    This does not sign commits that already have signatures.
 
40
    """
 
41
    # Note that this signs everything on the branch's ancestry
 
42
    # (both mainline and merged), but not other revisions that may be in the
 
43
    # repository
 
44
 
 
45
    takes_options = [
 
46
        Option('dry-run',
 
47
               help='Don\'t actually sign anything, just print'
 
48
               ' the revisions that would be signed.'),
 
49
        ]
 
50
    takes_args = ['location?', 'committer?']
 
51
 
 
52
    def run(self, location=None, committer=None, dry_run=False):
 
53
        if location is None:
 
54
            bzrdir = controldir.ControlDir.open_containing('.')[0]
 
55
        else:
 
56
            # Passed in locations should be exact
 
57
            bzrdir = controldir.ControlDir.open(location)
 
58
        branch = bzrdir.open_branch()
 
59
        repo = branch.repository
 
60
        branch_config = branch.get_config_stack()
 
61
 
 
62
        if committer is None:
 
63
            committer = branch_config.get('email')
 
64
        gpg_strategy = gpg.GPGStrategy(branch_config)
 
65
 
 
66
        count = 0
 
67
        with repo.lock_write():
 
68
            graph = repo.get_graph()
 
69
            repo.start_write_group()
 
70
            try:
 
71
                for rev_id, parents in graph.iter_ancestry(
 
72
                        [branch.last_revision()]):
 
73
                    if _mod_revision.is_null(rev_id):
 
74
                        continue
 
75
                    if parents is None:
 
76
                        # Ignore ghosts
 
77
                        continue
 
78
                    if repo.has_signature_for_revision_id(rev_id):
 
79
                        continue
 
80
                    rev = repo.get_revision(rev_id)
 
81
                    if rev.committer != committer:
 
82
                        continue
 
83
                    # We have a revision without a signature who has a
 
84
                    # matching committer, start signing
 
85
                    self.outf.write("%s\n" % rev_id)
 
86
                    count += 1
 
87
                    if not dry_run:
 
88
                        repo.sign_revision(rev_id, gpg_strategy)
 
89
            except BaseException:
 
90
                repo.abort_write_group()
 
91
                raise
 
92
            else:
 
93
                repo.commit_write_group()
 
94
        self.outf.write(
 
95
            ngettext('Signed %d revision.\n', 'Signed %d revisions.\n',
 
96
                     count) % count)
 
97
 
 
98
 
 
99
class cmd_verify_signatures(Command):
 
100
    __doc__ = """Verify all commit signatures.
 
101
 
 
102
    Verifies that all commits in the branch are signed by known GnuPG keys.
 
103
    """
 
104
 
 
105
    takes_options = [
 
106
        Option('acceptable-keys',
 
107
               help='Comma separated list of GPG key patterns which are'
 
108
               ' acceptable for verification.',
 
109
               short_name='k',
 
110
               type=text_type,),
 
111
        'revision',
 
112
        'verbose',
 
113
        ]
 
114
    takes_args = ['location?']
 
115
 
 
116
    def run(self, acceptable_keys=None, revision=None, verbose=None,
 
117
            location=u'.'):
 
118
        bzrdir = controldir.ControlDir.open_containing(location)[0]
 
119
        branch = bzrdir.open_branch()
 
120
        repo = branch.repository
 
121
        branch_config = branch.get_config_stack()
 
122
        gpg_strategy = gpg.GPGStrategy(branch_config)
 
123
 
 
124
        gpg_strategy.set_acceptable_keys(acceptable_keys)
 
125
 
 
126
        def write(string):
 
127
            self.outf.write(string + "\n")
 
128
 
 
129
        def write_verbose(string):
 
130
            self.outf.write("  " + string + "\n")
 
131
 
 
132
        self.add_cleanup(repo.lock_read().unlock)
 
133
        # get our list of revisions
 
134
        revisions = []
 
135
        if revision is not None:
 
136
            if len(revision) == 1:
 
137
                revno, rev_id = revision[0].in_history(branch)
 
138
                revisions.append(rev_id)
 
139
            elif len(revision) == 2:
 
140
                from_revno, from_revid = revision[0].in_history(branch)
 
141
                to_revno, to_revid = revision[1].in_history(branch)
 
142
                if to_revid is None:
 
143
                    to_revno = branch.revno()
 
144
                if from_revno is None or to_revno is None:
 
145
                    raise errors.BzrCommandError(
 
146
                        gettext('Cannot verify a range of non-revision-history'
 
147
                                ' revisions'))
 
148
                for revno in range(from_revno, to_revno + 1):
 
149
                    revisions.append(branch.get_rev_id(revno))
 
150
        else:
 
151
            # all revisions by default including merges
 
152
            graph = repo.get_graph()
 
153
            revisions = []
 
154
            for rev_id, parents in graph.iter_ancestry(
 
155
                    [branch.last_revision()]):
 
156
                if _mod_revision.is_null(rev_id):
 
157
                    continue
 
158
                if parents is None:
 
159
                    # Ignore ghosts
 
160
                    continue
 
161
                revisions.append(rev_id)
 
162
        count, result, all_verifiable = gpg.bulk_verify_signatures(
 
163
            repo, revisions, gpg_strategy)
 
164
        if all_verifiable:
 
165
            write(gettext("All commits signed with verifiable keys"))
 
166
            if verbose:
 
167
                for message in gpg.verbose_valid_message(result):
 
168
                    write_verbose(message)
 
169
            return 0
 
170
        else:
 
171
            write(gpg.valid_commits_message(count))
 
172
            if verbose:
 
173
                for message in gpg.verbose_valid_message(result):
 
174
                    write_verbose(message)
 
175
            write(gpg.expired_commit_message(count))
 
176
            if verbose:
 
177
                for message in gpg.verbose_expired_key_message(result, repo):
 
178
                    write_verbose(message)
 
179
            write(gpg.unknown_key_message(count))
 
180
            if verbose:
 
181
                for message in gpg.verbose_missing_key_message(result):
 
182
                    write_verbose(message)
 
183
            write(gpg.commit_not_valid_message(count))
 
184
            if verbose:
 
185
                for message in gpg.verbose_not_valid_message(result, repo):
 
186
                    write_verbose(message)
 
187
            write(gpg.commit_not_signed_message(count))
 
188
            if verbose:
 
189
                for message in gpg.verbose_not_signed_message(result, repo):
 
190
                    write_verbose(message)
 
191
            return 1