@@ -150,6 +150,7 @@ enum atom_type {
150
150
ATOM_BODY ,
151
151
ATOM_TRAILERS ,
152
152
ATOM_CONTENTS ,
153
+ ATOM_SIGNATURE ,
153
154
ATOM_RAW ,
154
155
ATOM_UPSTREAM ,
155
156
ATOM_PUSH ,
@@ -215,6 +216,10 @@ static struct used_atom {
215
216
struct email_option {
216
217
enum { EO_RAW , EO_TRIM , EO_LOCALPART } option ;
217
218
} email_option ;
219
+ struct {
220
+ enum { S_BARE , S_GRADE , S_SIGNER , S_KEY ,
221
+ S_FINGERPRINT , S_PRI_KEY_FP , S_TRUST_LEVEL } option ;
222
+ } signature ;
218
223
struct refname_atom refname ;
219
224
char * head ;
220
225
} u ;
@@ -407,8 +412,37 @@ static int subject_atom_parser(struct ref_format *format UNUSED,
407
412
return 0 ;
408
413
}
409
414
410
- static int trailers_atom_parser (struct ref_format * format UNUSED ,
411
- struct used_atom * atom ,
415
+ static int parse_signature_option (const char * arg )
416
+ {
417
+ if (!arg )
418
+ return S_BARE ;
419
+ else if (!strcmp (arg , "signer" ))
420
+ return S_SIGNER ;
421
+ else if (!strcmp (arg , "grade" ))
422
+ return S_GRADE ;
423
+ else if (!strcmp (arg , "key" ))
424
+ return S_KEY ;
425
+ else if (!strcmp (arg , "fingerprint" ))
426
+ return S_FINGERPRINT ;
427
+ else if (!strcmp (arg , "primarykeyfingerprint" ))
428
+ return S_PRI_KEY_FP ;
429
+ else if (!strcmp (arg , "trustlevel" ))
430
+ return S_TRUST_LEVEL ;
431
+ return -1 ;
432
+ }
433
+
434
+ static int signature_atom_parser (struct ref_format * format UNUSED ,
435
+ struct used_atom * atom ,
436
+ const char * arg , struct strbuf * err )
437
+ {
438
+ int opt = parse_signature_option (arg );
439
+ if (opt < 0 )
440
+ return err_bad_arg (err , "signature" , arg );
441
+ atom -> u .signature .option = opt ;
442
+ return 0 ;
443
+ }
444
+
445
+ static int trailers_atom_parser (struct ref_format * format , struct used_atom * atom ,
412
446
const char * arg , struct strbuf * err )
413
447
{
414
448
atom -> u .contents .trailer_opts .no_divider = 1 ;
@@ -668,6 +702,7 @@ static struct {
668
702
[ATOM_BODY ] = { "body" , SOURCE_OBJ , FIELD_STR , body_atom_parser },
669
703
[ATOM_TRAILERS ] = { "trailers" , SOURCE_OBJ , FIELD_STR , trailers_atom_parser },
670
704
[ATOM_CONTENTS ] = { "contents" , SOURCE_OBJ , FIELD_STR , contents_atom_parser },
705
+ [ATOM_SIGNATURE ] = { "signature" , SOURCE_OBJ , FIELD_STR , signature_atom_parser },
671
706
[ATOM_RAW ] = { "raw" , SOURCE_OBJ , FIELD_STR , raw_atom_parser },
672
707
[ATOM_UPSTREAM ] = { "upstream" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
673
708
[ATOM_PUSH ] = { "push" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
@@ -1405,6 +1440,92 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
1405
1440
}
1406
1441
}
1407
1442
1443
+ static void grab_signature (struct atom_value * val , int deref , struct object * obj )
1444
+ {
1445
+ int i ;
1446
+ struct commit * commit = (struct commit * ) obj ;
1447
+ struct signature_check sigc = { 0 };
1448
+ int signature_checked = 0 ;
1449
+
1450
+ for (i = 0 ; i < used_atom_cnt ; i ++ ) {
1451
+ struct used_atom * atom = & used_atom [i ];
1452
+ const char * name = atom -> name ;
1453
+ struct atom_value * v = & val [i ];
1454
+ int opt ;
1455
+
1456
+ if (!!deref != (* name == '*' ))
1457
+ continue ;
1458
+ if (deref )
1459
+ name ++ ;
1460
+
1461
+ if (!skip_prefix (name , "signature" , & name ) ||
1462
+ (* name && * name != ':' ))
1463
+ continue ;
1464
+ if (!* name )
1465
+ name = NULL ;
1466
+ else
1467
+ name ++ ;
1468
+
1469
+ opt = parse_signature_option (name );
1470
+ if (opt < 0 )
1471
+ continue ;
1472
+
1473
+ if (!signature_checked ) {
1474
+ check_commit_signature (commit , & sigc );
1475
+ signature_checked = 1 ;
1476
+ }
1477
+
1478
+ switch (opt ) {
1479
+ case S_BARE :
1480
+ v -> s = xstrdup (sigc .output ? sigc .output : "" );
1481
+ break ;
1482
+ case S_SIGNER :
1483
+ v -> s = xstrdup (sigc .signer ? sigc .signer : "" );
1484
+ break ;
1485
+ case S_GRADE :
1486
+ switch (sigc .result ) {
1487
+ case 'G' :
1488
+ switch (sigc .trust_level ) {
1489
+ case TRUST_UNDEFINED :
1490
+ case TRUST_NEVER :
1491
+ v -> s = xstrfmt ("%c" , (char )'U' );
1492
+ break ;
1493
+ default :
1494
+ v -> s = xstrfmt ("%c" , (char )'G' );
1495
+ break ;
1496
+ }
1497
+ break ;
1498
+ case 'B' :
1499
+ case 'E' :
1500
+ case 'N' :
1501
+ case 'X' :
1502
+ case 'Y' :
1503
+ case 'R' :
1504
+ v -> s = xstrfmt ("%c" , (char )sigc .result );
1505
+ break ;
1506
+ }
1507
+ break ;
1508
+ case S_KEY :
1509
+ v -> s = xstrdup (sigc .key ? sigc .key : "" );
1510
+ break ;
1511
+ case S_FINGERPRINT :
1512
+ v -> s = xstrdup (sigc .fingerprint ?
1513
+ sigc .fingerprint : "" );
1514
+ break ;
1515
+ case S_PRI_KEY_FP :
1516
+ v -> s = xstrdup (sigc .primary_key_fingerprint ?
1517
+ sigc .primary_key_fingerprint : "" );
1518
+ break ;
1519
+ case S_TRUST_LEVEL :
1520
+ v -> s = xstrdup (gpg_trust_level_to_str (sigc .trust_level ));
1521
+ break ;
1522
+ }
1523
+ }
1524
+
1525
+ if (signature_checked )
1526
+ signature_check_clear (& sigc );
1527
+ }
1528
+
1408
1529
static void find_subpos (const char * buf ,
1409
1530
const char * * sub , size_t * sublen ,
1410
1531
const char * * body , size_t * bodylen ,
@@ -1598,6 +1719,7 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, s
1598
1719
grab_sub_body_contents (val , deref , data );
1599
1720
grab_person ("author" , val , deref , buf );
1600
1721
grab_person ("committer" , val , deref , buf );
1722
+ grab_signature (val , deref , obj );
1601
1723
break ;
1602
1724
case OBJ_TREE :
1603
1725
/* grab_tree_values(val, deref, obj, buf, sz); */
0 commit comments