|
5 | 5 | #include "gpg-interface.h"
|
6 | 6 | #include "hex.h"
|
7 | 7 | #include "parse-options.h"
|
| 8 | +#include "run-command.h" |
8 | 9 | #include "refs.h"
|
9 | 10 | #include "wildmatch.h"
|
10 | 11 | #include "object-name.h"
|
@@ -146,6 +147,7 @@ enum atom_type {
|
146 | 147 | ATOM_TAGGERDATE,
|
147 | 148 | ATOM_CREATOR,
|
148 | 149 | ATOM_CREATORDATE,
|
| 150 | + ATOM_DESCRIBE, |
149 | 151 | ATOM_SUBJECT,
|
150 | 152 | ATOM_BODY,
|
151 | 153 | ATOM_TRAILERS,
|
@@ -220,6 +222,7 @@ static struct used_atom {
|
220 | 222 | enum { S_BARE, S_GRADE, S_SIGNER, S_KEY,
|
221 | 223 | S_FINGERPRINT, S_PRI_KEY_FP, S_TRUST_LEVEL } option;
|
222 | 224 | } signature;
|
| 225 | + const char **describe_args; |
223 | 226 | struct refname_atom refname;
|
224 | 227 | char *head;
|
225 | 228 | } u;
|
@@ -600,6 +603,87 @@ static int contents_atom_parser(struct ref_format *format, struct used_atom *ato
|
600 | 603 | return 0;
|
601 | 604 | }
|
602 | 605 |
|
| 606 | +static int describe_atom_option_parser(struct strvec *args, const char **arg, |
| 607 | + struct strbuf *err) |
| 608 | +{ |
| 609 | + const char *argval; |
| 610 | + size_t arglen = 0; |
| 611 | + int optval = 0; |
| 612 | + |
| 613 | + if (match_atom_bool_arg(*arg, "tags", arg, &optval)) { |
| 614 | + if (!optval) |
| 615 | + strvec_push(args, "--no-tags"); |
| 616 | + else |
| 617 | + strvec_push(args, "--tags"); |
| 618 | + return 1; |
| 619 | + } |
| 620 | + |
| 621 | + if (match_atom_arg_value(*arg, "abbrev", arg, &argval, &arglen)) { |
| 622 | + char *endptr; |
| 623 | + |
| 624 | + if (!arglen) |
| 625 | + return strbuf_addf_ret(err, -1, |
| 626 | + _("argument expected for %s"), |
| 627 | + "describe:abbrev"); |
| 628 | + if (strtol(argval, &endptr, 10) < 0) |
| 629 | + return strbuf_addf_ret(err, -1, |
| 630 | + _("positive value expected %s=%s"), |
| 631 | + "describe:abbrev", argval); |
| 632 | + if (endptr - argval != arglen) |
| 633 | + return strbuf_addf_ret(err, -1, |
| 634 | + _("cannot fully parse %s=%s"), |
| 635 | + "describe:abbrev", argval); |
| 636 | + |
| 637 | + strvec_pushf(args, "--abbrev=%.*s", (int)arglen, argval); |
| 638 | + return 1; |
| 639 | + } |
| 640 | + |
| 641 | + if (match_atom_arg_value(*arg, "match", arg, &argval, &arglen)) { |
| 642 | + if (!arglen) |
| 643 | + return strbuf_addf_ret(err, -1, |
| 644 | + _("value expected %s="), |
| 645 | + "describe:match"); |
| 646 | + |
| 647 | + strvec_pushf(args, "--match=%.*s", (int)arglen, argval); |
| 648 | + return 1; |
| 649 | + } |
| 650 | + |
| 651 | + if (match_atom_arg_value(*arg, "exclude", arg, &argval, &arglen)) { |
| 652 | + if (!arglen) |
| 653 | + return strbuf_addf_ret(err, -1, |
| 654 | + _("value expected %s="), |
| 655 | + "describe:exclude"); |
| 656 | + |
| 657 | + strvec_pushf(args, "--exclude=%.*s", (int)arglen, argval); |
| 658 | + return 1; |
| 659 | + } |
| 660 | + |
| 661 | + return 0; |
| 662 | +} |
| 663 | + |
| 664 | +static int describe_atom_parser(struct ref_format *format UNUSED, |
| 665 | + struct used_atom *atom, |
| 666 | + const char *arg, struct strbuf *err) |
| 667 | +{ |
| 668 | + struct strvec args = STRVEC_INIT; |
| 669 | + |
| 670 | + for (;;) { |
| 671 | + int found = 0; |
| 672 | + const char *bad_arg = arg; |
| 673 | + |
| 674 | + if (!arg || !*arg) |
| 675 | + break; |
| 676 | + |
| 677 | + found = describe_atom_option_parser(&args, &arg, err); |
| 678 | + if (found < 0) |
| 679 | + return found; |
| 680 | + if (!found) |
| 681 | + return err_bad_arg(err, "describe", bad_arg); |
| 682 | + } |
| 683 | + atom->u.describe_args = strvec_detach(&args); |
| 684 | + return 0; |
| 685 | +} |
| 686 | + |
603 | 687 | static int raw_atom_parser(struct ref_format *format UNUSED,
|
604 | 688 | struct used_atom *atom,
|
605 | 689 | const char *arg, struct strbuf *err)
|
@@ -802,6 +886,7 @@ static struct {
|
802 | 886 | [ATOM_TAGGERDATE] = { "taggerdate", SOURCE_OBJ, FIELD_TIME },
|
803 | 887 | [ATOM_CREATOR] = { "creator", SOURCE_OBJ },
|
804 | 888 | [ATOM_CREATORDATE] = { "creatordate", SOURCE_OBJ, FIELD_TIME },
|
| 889 | + [ATOM_DESCRIBE] = { "describe", SOURCE_OBJ, FIELD_STR, describe_atom_parser }, |
805 | 890 | [ATOM_SUBJECT] = { "subject", SOURCE_OBJ, FIELD_STR, subject_atom_parser },
|
806 | 891 | [ATOM_BODY] = { "body", SOURCE_OBJ, FIELD_STR, body_atom_parser },
|
807 | 892 | [ATOM_TRAILERS] = { "trailers", SOURCE_OBJ, FIELD_STR, trailers_atom_parser },
|
@@ -1708,6 +1793,44 @@ static void append_lines(struct strbuf *out, const char *buf, unsigned long size
|
1708 | 1793 | }
|
1709 | 1794 | }
|
1710 | 1795 |
|
| 1796 | +static void grab_describe_values(struct atom_value *val, int deref, |
| 1797 | + struct object *obj) |
| 1798 | +{ |
| 1799 | + struct commit *commit = (struct commit *)obj; |
| 1800 | + int i; |
| 1801 | + |
| 1802 | + for (i = 0; i < used_atom_cnt; i++) { |
| 1803 | + struct used_atom *atom = &used_atom[i]; |
| 1804 | + enum atom_type type = atom->atom_type; |
| 1805 | + const char *name = atom->name; |
| 1806 | + struct atom_value *v = &val[i]; |
| 1807 | + |
| 1808 | + struct child_process cmd = CHILD_PROCESS_INIT; |
| 1809 | + struct strbuf out = STRBUF_INIT; |
| 1810 | + struct strbuf err = STRBUF_INIT; |
| 1811 | + |
| 1812 | + if (type != ATOM_DESCRIBE) |
| 1813 | + continue; |
| 1814 | + |
| 1815 | + if (!!deref != (*name == '*')) |
| 1816 | + continue; |
| 1817 | + |
| 1818 | + cmd.git_cmd = 1; |
| 1819 | + strvec_push(&cmd.args, "describe"); |
| 1820 | + strvec_pushv(&cmd.args, atom->u.describe_args); |
| 1821 | + strvec_push(&cmd.args, oid_to_hex(&commit->object.oid)); |
| 1822 | + if (pipe_command(&cmd, NULL, 0, &out, 0, &err, 0) < 0) { |
| 1823 | + error(_("failed to run 'describe'")); |
| 1824 | + v->s = xstrdup(""); |
| 1825 | + continue; |
| 1826 | + } |
| 1827 | + strbuf_rtrim(&out); |
| 1828 | + v->s = strbuf_detach(&out, NULL); |
| 1829 | + |
| 1830 | + strbuf_release(&err); |
| 1831 | + } |
| 1832 | +} |
| 1833 | + |
1711 | 1834 | /* See grab_values */
|
1712 | 1835 | static void grab_sub_body_contents(struct atom_value *val, int deref, struct expand_data *data)
|
1713 | 1836 | {
|
@@ -1817,13 +1940,15 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, s
|
1817 | 1940 | grab_tag_values(val, deref, obj);
|
1818 | 1941 | grab_sub_body_contents(val, deref, data);
|
1819 | 1942 | grab_person("tagger", val, deref, buf);
|
| 1943 | + grab_describe_values(val, deref, obj); |
1820 | 1944 | break;
|
1821 | 1945 | case OBJ_COMMIT:
|
1822 | 1946 | grab_commit_values(val, deref, obj);
|
1823 | 1947 | grab_sub_body_contents(val, deref, data);
|
1824 | 1948 | grab_person("author", val, deref, buf);
|
1825 | 1949 | grab_person("committer", val, deref, buf);
|
1826 | 1950 | grab_signature(val, deref, obj);
|
| 1951 | + grab_describe_values(val, deref, obj); |
1827 | 1952 | break;
|
1828 | 1953 | case OBJ_TREE:
|
1829 | 1954 | /* grab_tree_values(val, deref, obj, buf, sz); */
|
|
0 commit comments