/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: Jelmer Vernooij
  • Date: 2020-05-24 00:39:50 UTC
  • mto: This revision was merged to the branch mainline in revision 7504.
  • Revision ID: jelmer@jelmer.uk-20200524003950-bbc545r76vc5yajg
Add github action.

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 . import (
 
20
    controldir,
 
21
    errors,
 
22
    gpg,
 
23
    repository as _mod_repository,
 
24
    revision as _mod_revision,
 
25
    )
 
26
from .commands import Command
 
27
from .option import Option
 
28
from .i18n import gettext, ngettext
 
29
 
 
30
 
 
31
class cmd_sign_my_commits(Command):
 
32
    __doc__ = """Sign all commits by a given committer.
 
33
 
 
34
    If location is not specified the local tree is used.
 
35
    If committer is not specified the default committer is used.
 
36
 
 
37
    This does not sign commits that already have signatures.
 
38
    """
 
39
    # Note that this signs everything on the branch's ancestry
 
40
    # (both mainline and merged), but not other revisions that may be in the
 
41
    # repository
 
42
 
 
43
    takes_options = [
 
44
        Option('dry-run',
 
45
               help='Don\'t actually sign anything, just print'
 
46
               ' the revisions that would be signed.'),
 
47
        ]
 
48
    takes_args = ['location?', 'committer?']
 
49
 
 
50
    def run(self, location=None, committer=None, dry_run=False):
 
51
        if location is None:
 
52
            bzrdir = controldir.ControlDir.open_containing('.')[0]
 
53
        else:
 
54
            # Passed in locations should be exact
 
55
            bzrdir = controldir.ControlDir.open(location)
 
56
        branch = bzrdir.open_branch()
 
57
        repo = branch.repository
 
58
        branch_config = branch.get_config_stack()
 
59
 
 
60
        if committer is None:
 
61
            committer = branch_config.get('email')
 
62
        gpg_strategy = gpg.GPGStrategy(branch_config)
 
63
 
 
64
        count = 0
 
65
        with repo.lock_write():
 
66
            graph = repo.get_graph()
 
67
            with _mod_repository.WriteGroup(repo):
 
68
                for rev_id, parents in graph.iter_ancestry(
 
69
                        [branch.last_revision()]):
 
70
                    if _mod_revision.is_null(rev_id):
 
71
                        continue
 
72
                    if parents is None:
 
73
                        # Ignore ghosts
 
74
                        continue
 
75
                    if repo.has_signature_for_revision_id(rev_id):
 
76
                        continue
 
77
                    rev = repo.get_revision(rev_id)
 
78
                    if rev.committer != committer:
 
79
                        continue
 
80
                    # We have a revision without a signature who has a
 
81
                    # matching committer, start signing
 
82
                    self.outf.write("%s\n" % rev_id)
 
83
                    count += 1
 
84
                    if not dry_run:
 
85
                        repo.sign_revision(rev_id, gpg_strategy)
 
86
        self.outf.write(
 
87
            ngettext('Signed %d revision.\n', 'Signed %d revisions.\n',
 
88
                     count) % count)
 
89
 
 
90
 
 
91
class cmd_verify_signatures(Command):
 
92
    __doc__ = """Verify all commit signatures.
 
93
 
 
94
    Verifies that all commits in the branch are signed by known GnuPG keys.
 
95
    """
 
96
 
 
97
    takes_options = [
 
98
        Option('acceptable-keys',
 
99
               help='Comma separated list of GPG key patterns which are'
 
100
               ' acceptable for verification.',
 
101
               short_name='k',
 
102
               type=str,),
 
103
        'revision',
 
104
        'verbose',
 
105
        ]
 
106
    takes_args = ['location?']
 
107
 
 
108
    def run(self, acceptable_keys=None, revision=None, verbose=None,
 
109
            location=u'.'):
 
110
        bzrdir = controldir.ControlDir.open_containing(location)[0]
 
111
        branch = bzrdir.open_branch()
 
112
        repo = branch.repository
 
113
        branch_config = branch.get_config_stack()
 
114
        gpg_strategy = gpg.GPGStrategy(branch_config)
 
115
 
 
116
        gpg_strategy.set_acceptable_keys(acceptable_keys)
 
117
 
 
118
        def write(string):
 
119
            self.outf.write(string + "\n")
 
120
 
 
121
        def write_verbose(string):
 
122
            self.outf.write("  " + string + "\n")
 
123
 
 
124
        self.add_cleanup(repo.lock_read().unlock)
 
125
        # get our list of revisions
 
126
        revisions = []
 
127
        if revision is not None:
 
128
            if len(revision) == 1:
 
129
                revno, rev_id = revision[0].in_history(branch)
 
130
                revisions.append(rev_id)
 
131
            elif len(revision) == 2:
 
132
                from_revno, from_revid = revision[0].in_history(branch)
 
133
                to_revno, to_revid = revision[1].in_history(branch)
 
134
                if to_revid is None:
 
135
                    to_revno = branch.revno()
 
136
                if from_revno is None or to_revno is None:
 
137
                    raise errors.BzrCommandError(
 
138
                        gettext('Cannot verify a range of non-revision-history'
 
139
                                ' revisions'))
 
140
                for revno in range(from_revno, to_revno + 1):
 
141
                    revisions.append(branch.get_rev_id(revno))
 
142
        else:
 
143
            # all revisions by default including merges
 
144
            graph = repo.get_graph()
 
145
            revisions = []
 
146
            for rev_id, parents in graph.iter_ancestry(
 
147
                    [branch.last_revision()]):
 
148
                if _mod_revision.is_null(rev_id):
 
149
                    continue
 
150
                if parents is None:
 
151
                    # Ignore ghosts
 
152
                    continue
 
153
                revisions.append(rev_id)
 
154
        count, result, all_verifiable = gpg.bulk_verify_signatures(
 
155
            repo, revisions, gpg_strategy)
 
156
        if all_verifiable:
 
157
            write(gettext("All commits signed with verifiable keys"))
 
158
            if verbose:
 
159
                for message in gpg.verbose_valid_message(result):
 
160
                    write_verbose(message)
 
161
            return 0
 
162
        else:
 
163
            write(gpg.valid_commits_message(count))
 
164
            if verbose:
 
165
                for message in gpg.verbose_valid_message(result):
 
166
                    write_verbose(message)
 
167
            write(gpg.expired_commit_message(count))
 
168
            if verbose:
 
169
                for message in gpg.verbose_expired_key_message(result, repo):
 
170
                    write_verbose(message)
 
171
            write(gpg.unknown_key_message(count))
 
172
            if verbose:
 
173
                for message in gpg.verbose_missing_key_message(result):
 
174
                    write_verbose(message)
 
175
            write(gpg.commit_not_valid_message(count))
 
176
            if verbose:
 
177
                for message in gpg.verbose_not_valid_message(result, repo):
 
178
                    write_verbose(message)
 
179
            write(gpg.commit_not_signed_message(count))
 
180
            if verbose:
 
181
                for message in gpg.verbose_not_signed_message(result, repo):
 
182
                    write_verbose(message)
 
183
            return 1