]> git.ipfire.org Git - thirdparty/git.git/blob - builtin/mktag.c
fsck.c: refactor and rename common config callback
[thirdparty/git.git] / builtin / mktag.c
1 #include "builtin.h"
2 #include "parse-options.h"
3 #include "tag.h"
4 #include "replace-object.h"
5 #include "object-store.h"
6 #include "fsck.h"
7 #include "config.h"
8
9 static char const * const builtin_mktag_usage[] = {
10 N_("git mktag"),
11 NULL
12 };
13 static int option_strict = 1;
14
15 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
16
17 static int mktag_fsck_error_func(struct fsck_options *o,
18 const struct object_id *oid,
19 enum object_type object_type,
20 int msg_type, const char *message)
21 {
22 switch (msg_type) {
23 case FSCK_WARN:
24 if (!option_strict) {
25 fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
26 return 0;
27
28 }
29 /* fallthrough */
30 case FSCK_ERROR:
31 /*
32 * We treat both warnings and errors as errors, things
33 * like missing "tagger" lines are "only" warnings
34 * under fsck, we've always considered them an error.
35 */
36 fprintf_ln(stderr, _("error: tag input does not pass fsck: %s"), message);
37 return 1;
38 default:
39 BUG(_("%d (FSCK_IGNORE?) should never trigger this callback"),
40 msg_type);
41 }
42 }
43
44 static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
45 {
46 int ret;
47 enum object_type type;
48 unsigned long size;
49 void *buffer;
50 const struct object_id *repl;
51
52 buffer = read_object_file(tagged_oid, &type, &size);
53 if (!buffer)
54 die(_("could not read tagged object '%s'"),
55 oid_to_hex(tagged_oid));
56 if (type != *tagged_type)
57 die(_("object '%s' tagged as '%s', but is a '%s' type"),
58 oid_to_hex(tagged_oid),
59 type_name(*tagged_type), type_name(type));
60
61 repl = lookup_replace_object(the_repository, tagged_oid);
62 ret = check_object_signature(the_repository, repl,
63 buffer, size, type_name(*tagged_type));
64 free(buffer);
65
66 return ret;
67 }
68
69 int cmd_mktag(int argc, const char **argv, const char *prefix)
70 {
71 static struct option builtin_mktag_options[] = {
72 OPT_BOOL(0, "strict", &option_strict,
73 N_("enable more strict checking")),
74 OPT_END(),
75 };
76 struct strbuf buf = STRBUF_INIT;
77 struct object_id tagged_oid;
78 int tagged_type;
79 struct object_id result;
80
81 argc = parse_options(argc, argv, NULL,
82 builtin_mktag_options,
83 builtin_mktag_usage, 0);
84
85 if (strbuf_read(&buf, 0, 0) < 0)
86 die_errno(_("could not read from stdin"));
87
88 fsck_options.error_func = mktag_fsck_error_func;
89 fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
90 /* config might set fsck.extraHeaderEntry=* again */
91 git_config(git_fsck_config, &fsck_options);
92 if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
93 &tagged_oid, &tagged_type))
94 die(_("tag on stdin did not pass our strict fsck check"));
95
96 if (verify_object_in_tag(&tagged_oid, &tagged_type))
97 die(_("tag on stdin did not refer to a valid object"));
98
99 if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
100 die(_("unable to write tag file"));
101
102 strbuf_release(&buf);
103 puts(oid_to_hex(&result));
104 return 0;
105 }