Merge branch 'ks/ref-filter-signature'
The "git for-each-ref" family of commands learned placeholders related to GPG signature verification. * ks/ref-filter-signature: ref-filter: add new "signature" atom t/lib-gpg: introduce new prereq GPG2
This commit is contained in:
126
ref-filter.c
126
ref-filter.c
@ -150,6 +150,7 @@ enum atom_type {
|
||||
ATOM_BODY,
|
||||
ATOM_TRAILERS,
|
||||
ATOM_CONTENTS,
|
||||
ATOM_SIGNATURE,
|
||||
ATOM_RAW,
|
||||
ATOM_UPSTREAM,
|
||||
ATOM_PUSH,
|
||||
@ -215,6 +216,10 @@ static struct used_atom {
|
||||
struct email_option {
|
||||
enum { EO_RAW, EO_TRIM, EO_LOCALPART } option;
|
||||
} email_option;
|
||||
struct {
|
||||
enum { S_BARE, S_GRADE, S_SIGNER, S_KEY,
|
||||
S_FINGERPRINT, S_PRI_KEY_FP, S_TRUST_LEVEL } option;
|
||||
} signature;
|
||||
struct refname_atom refname;
|
||||
char *head;
|
||||
} u;
|
||||
@ -407,8 +412,37 @@ static int subject_atom_parser(struct ref_format *format UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trailers_atom_parser(struct ref_format *format UNUSED,
|
||||
struct used_atom *atom,
|
||||
static int parse_signature_option(const char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
return S_BARE;
|
||||
else if (!strcmp(arg, "signer"))
|
||||
return S_SIGNER;
|
||||
else if (!strcmp(arg, "grade"))
|
||||
return S_GRADE;
|
||||
else if (!strcmp(arg, "key"))
|
||||
return S_KEY;
|
||||
else if (!strcmp(arg, "fingerprint"))
|
||||
return S_FINGERPRINT;
|
||||
else if (!strcmp(arg, "primarykeyfingerprint"))
|
||||
return S_PRI_KEY_FP;
|
||||
else if (!strcmp(arg, "trustlevel"))
|
||||
return S_TRUST_LEVEL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int signature_atom_parser(struct ref_format *format UNUSED,
|
||||
struct used_atom *atom,
|
||||
const char *arg, struct strbuf *err)
|
||||
{
|
||||
int opt = parse_signature_option(arg);
|
||||
if (opt < 0)
|
||||
return err_bad_arg(err, "signature", arg);
|
||||
atom->u.signature.option = opt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trailers_atom_parser(struct ref_format *format, struct used_atom *atom,
|
||||
const char *arg, struct strbuf *err)
|
||||
{
|
||||
atom->u.contents.trailer_opts.no_divider = 1;
|
||||
@ -668,6 +702,7 @@ static struct {
|
||||
[ATOM_BODY] = { "body", SOURCE_OBJ, FIELD_STR, body_atom_parser },
|
||||
[ATOM_TRAILERS] = { "trailers", SOURCE_OBJ, FIELD_STR, trailers_atom_parser },
|
||||
[ATOM_CONTENTS] = { "contents", SOURCE_OBJ, FIELD_STR, contents_atom_parser },
|
||||
[ATOM_SIGNATURE] = { "signature", SOURCE_OBJ, FIELD_STR, signature_atom_parser },
|
||||
[ATOM_RAW] = { "raw", SOURCE_OBJ, FIELD_STR, raw_atom_parser },
|
||||
[ATOM_UPSTREAM] = { "upstream", SOURCE_NONE, FIELD_STR, remote_ref_atom_parser },
|
||||
[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
|
||||
}
|
||||
}
|
||||
|
||||
static void grab_signature(struct atom_value *val, int deref, struct object *obj)
|
||||
{
|
||||
int i;
|
||||
struct commit *commit = (struct commit *) obj;
|
||||
struct signature_check sigc = { 0 };
|
||||
int signature_checked = 0;
|
||||
|
||||
for (i = 0; i < used_atom_cnt; i++) {
|
||||
struct used_atom *atom = &used_atom[i];
|
||||
const char *name = atom->name;
|
||||
struct atom_value *v = &val[i];
|
||||
int opt;
|
||||
|
||||
if (!!deref != (*name == '*'))
|
||||
continue;
|
||||
if (deref)
|
||||
name++;
|
||||
|
||||
if (!skip_prefix(name, "signature", &name) ||
|
||||
(*name && *name != ':'))
|
||||
continue;
|
||||
if (!*name)
|
||||
name = NULL;
|
||||
else
|
||||
name++;
|
||||
|
||||
opt = parse_signature_option(name);
|
||||
if (opt < 0)
|
||||
continue;
|
||||
|
||||
if (!signature_checked) {
|
||||
check_commit_signature(commit, &sigc);
|
||||
signature_checked = 1;
|
||||
}
|
||||
|
||||
switch (opt) {
|
||||
case S_BARE:
|
||||
v->s = xstrdup(sigc.output ? sigc.output: "");
|
||||
break;
|
||||
case S_SIGNER:
|
||||
v->s = xstrdup(sigc.signer ? sigc.signer : "");
|
||||
break;
|
||||
case S_GRADE:
|
||||
switch (sigc.result) {
|
||||
case 'G':
|
||||
switch (sigc.trust_level) {
|
||||
case TRUST_UNDEFINED:
|
||||
case TRUST_NEVER:
|
||||
v->s = xstrfmt("%c", (char)'U');
|
||||
break;
|
||||
default:
|
||||
v->s = xstrfmt("%c", (char)'G');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
case 'E':
|
||||
case 'N':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'R':
|
||||
v->s = xstrfmt("%c", (char)sigc.result);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case S_KEY:
|
||||
v->s = xstrdup(sigc.key ? sigc.key : "");
|
||||
break;
|
||||
case S_FINGERPRINT:
|
||||
v->s = xstrdup(sigc.fingerprint ?
|
||||
sigc.fingerprint : "");
|
||||
break;
|
||||
case S_PRI_KEY_FP:
|
||||
v->s = xstrdup(sigc.primary_key_fingerprint ?
|
||||
sigc.primary_key_fingerprint : "");
|
||||
break;
|
||||
case S_TRUST_LEVEL:
|
||||
v->s = xstrdup(gpg_trust_level_to_str(sigc.trust_level));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (signature_checked)
|
||||
signature_check_clear(&sigc);
|
||||
}
|
||||
|
||||
static void find_subpos(const char *buf,
|
||||
const char **sub, size_t *sublen,
|
||||
const char **body, size_t *bodylen,
|
||||
@ -1598,6 +1719,7 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, s
|
||||
grab_sub_body_contents(val, deref, data);
|
||||
grab_person("author", val, deref, buf);
|
||||
grab_person("committer", val, deref, buf);
|
||||
grab_signature(val, deref, obj);
|
||||
break;
|
||||
case OBJ_TREE:
|
||||
/* grab_tree_values(val, deref, obj, buf, sz); */
|
||||
|
Reference in New Issue
Block a user