/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 bzrlib/log.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-06-30 16:06:19 UTC
  • mfrom: (5971.1.80 bzr-gpgme)
  • Revision ID: pqm@pqm.ubuntu.com-20110630160619-3022zmfchft893nt
(jr) A new command ``bzr verify-signatures`` has been added to check that
 commits
 are correctly signed with trusted keys by GPG. This requires python-gpgme to
 be installed. ``bzr log`` has gained a ``--signatures`` option to list the
 validity of signatures for each commit. New config options
 ``acceptable_keys``
 and ``validate_signatures_in_log`` can be set to control options to these
 commands. (Jonathan Riddell)

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
    revision as _mod_revision,
75
75
    revisionspec,
76
76
    tsort,
 
77
    i18n,
77
78
    )
78
79
""")
79
80
 
230
231
                          delta_type=None,
231
232
                          diff_type=None, _match_using_deltas=True,
232
233
                          exclude_common_ancestry=False,
 
234
                          signature=False,
233
235
                          ):
234
236
    """Convenience function for making a logging request dictionary.
235
237
 
259
261
      generate; 1 for just the mainline; 0 for all levels.
260
262
 
261
263
    :param generate_tags: If True, include tags for matched revisions.
262
 
 
 
264
`
263
265
    :param delta_type: Either 'full', 'partial' or None.
264
266
      'full' means generate the complete delta - adds/deletes/modifies/etc;
265
267
      'partial' means filter the delta using specific_fileids;
277
279
 
278
280
    :param exclude_common_ancestry: Whether -rX..Y should be interpreted as a
279
281
      range operator or as a graph difference.
 
282
 
 
283
    :param signature: show digital signature information
280
284
    """
281
285
    return {
282
286
        'direction': direction,
290
294
        'delta_type': delta_type,
291
295
        'diff_type': diff_type,
292
296
        'exclude_common_ancestry': exclude_common_ancestry,
 
297
        'signature': signature,
293
298
        # Add 'private' attributes for features that may be deprecated
294
299
        '_match_using_deltas': _match_using_deltas,
295
300
    }
303
308
    return result
304
309
 
305
310
 
 
311
def format_signature_validity(rev_id, repo):
 
312
    """get the signature validity
 
313
    
 
314
    :param rev_id: revision id to validate
 
315
    :param repo: repository of revision
 
316
    :return: human readable string to print to log
 
317
    """
 
318
    from bzrlib import gpg
 
319
 
 
320
    gpg_strategy = gpg.GPGStrategy(None)
 
321
    result = repo.verify_revision(rev_id, gpg_strategy)
 
322
    if result[0] == gpg.SIGNATURE_VALID:
 
323
        return "valid signature from {0}".format(result[1])
 
324
    if result[0] == gpg.SIGNATURE_KEY_MISSING:
 
325
        return "unknown key {0}".format(result[1])
 
326
    if result[0] == gpg.SIGNATURE_NOT_VALID:
 
327
        return "invalid signature!"
 
328
    if result[0] == gpg.SIGNATURE_NOT_SIGNED:
 
329
        return "no signature"
 
330
 
 
331
 
306
332
class LogGenerator(object):
307
333
    """A generator of log revisions."""
308
334
 
360
386
            rqst['delta_type'] = None
361
387
        if not getattr(lf, 'supports_diff', False):
362
388
            rqst['diff_type'] = None
 
389
        if not getattr(lf, 'supports_signatures', False):
 
390
            rqst['signature'] = False
363
391
 
364
392
        # Find and print the interesting revisions
365
393
        generator = self._generator_factory(self.branch, rqst)
399
427
        levels = rqst.get('levels')
400
428
        limit = rqst.get('limit')
401
429
        diff_type = rqst.get('diff_type')
 
430
        show_signature = rqst.get('signature')
402
431
        log_count = 0
403
432
        revision_iterator = self._create_log_revision_iterator()
404
433
        for revs in revision_iterator:
410
439
                    diff = None
411
440
                else:
412
441
                    diff = self._format_diff(rev, rev_id, diff_type)
 
442
                if show_signature:
 
443
                    signature = format_signature_validity(rev_id,
 
444
                                                self.branch.repository)
 
445
                else:
 
446
                    signature = None
413
447
                yield LogRevision(rev, revno, merge_depth, delta,
414
 
                    self.rev_tag_dict.get(rev_id), diff)
 
448
                    self.rev_tag_dict.get(rev_id), diff, signature)
415
449
                if limit:
416
450
                    log_count += 1
417
451
                    if log_count >= limit:
1320
1354
    """
1321
1355
 
1322
1356
    def __init__(self, rev=None, revno=None, merge_depth=0, delta=None,
1323
 
                 tags=None, diff=None):
 
1357
                 tags=None, diff=None, signature=None):
1324
1358
        self.rev = rev
1325
1359
        if revno is None:
1326
1360
            self.revno = None
1330
1364
        self.delta = delta
1331
1365
        self.tags = tags
1332
1366
        self.diff = diff
 
1367
        self.signature = signature
1333
1368
 
1334
1369
 
1335
1370
class LogFormatter(object):
1362
1397
    - supports_diff must be True if this log formatter supports diffs.
1363
1398
      Otherwise the diff attribute may not be populated.
1364
1399
 
 
1400
    - supports_signatures must be True if this log formatter supports GPG
 
1401
      signatures.
 
1402
 
1365
1403
    Plugins can register functions to show custom revision properties using
1366
1404
    the properties_handler_registry. The registered function
1367
1405
    must respect the following interface description::
1558
1596
    supports_delta = True
1559
1597
    supports_tags = True
1560
1598
    supports_diff = True
 
1599
    supports_signatures = True
1561
1600
 
1562
1601
    def __init__(self, *args, **kwargs):
1563
1602
        super(LongLogFormatter, self).__init__(*args, **kwargs)
1602
1641
 
1603
1642
        lines.append('timestamp: %s' % (self.date_string(revision.rev),))
1604
1643
 
 
1644
        if revision.signature is not None:
 
1645
            lines.append('signature: ' + revision.signature)
 
1646
 
1605
1647
        lines.append('message:')
1606
1648
        if not revision.rev.message:
1607
1649
            lines.append('  (no message)')