Raw
1 #define USE_THE_REPOSITORY_VARIABLE
2 #define DISABLE_SIGN_COMPARE_WARNINGS
3
4 #include "test-tool.h"
5 #include "config.h"
6 #include "setup.h"
7 #include "string-list.h"
8
9 /*
10 * This program exposes the C API of the configuration mechanism
11 * as a set of simple commands in order to facilitate testing.
12 *
13 * Reads stdin and prints result of command to stdout:
14 *
15 * get_value -> prints the value with highest priority for the entered key
16 *
17 * get_value_multi -> prints all values for the entered key in increasing order
18 * of priority
19 *
20 * get -> print return value for the entered key
21 *
22 * get_int -> print integer value for the entered key or die
23 *
24 * get_bool -> print bool value for the entered key or die
25 *
26 * get_string -> print string value for the entered key or die
27 *
28 * configset_get_value -> returns value with the highest priority for the entered key
29 * from a config_set constructed from files entered as arguments.
30 *
31 * configset_get_value_multi -> returns value_list for the entered key sorted in
32 * ascending order of priority from a config_set
33 * constructed from files entered as arguments.
34 *
35 * iterate -> iterate over all values using repo_config(), and print some
36 * data for each
37 *
38 * git_config_int -> iterate over all values using repo_config() and print the
39 * integer value for the entered key or die
40 *
41 * Examples:
42 *
43 * To print the value with highest priority for key "foo.bAr Baz.rock":
44 * test-tool config get_value "foo.bAr Baz.rock"
45 *
46 */
47
48 static int iterate_cb(const char *var, const char *value,
49 const struct config_context *ctx,
50 void *data UNUSED)
51 {
52 const struct key_value_info *kvi = ctx->kvi;
53 static int nr;
54
55 if (nr++)
56 putchar('\n');
57
58 printf("key=%s\n", var);
59 printf("value=%s\n", value ? value : "(null)");
60 printf("origin=%s\n", config_origin_type_name(kvi->origin_type));
61 printf("name=%s\n", kvi->filename ? kvi->filename : "");
62 printf("lno=%d\n", kvi->linenr);
63 printf("scope=%s\n", config_scope_name(kvi->scope));
64
65 return 0;
66 }
67
68 static int parse_int_cb(const char *var, const char *value,
69 const struct config_context *ctx, void *data)
70 {
71 const char *key_to_match = data;
72
73 if (!strcmp(key_to_match, var)) {
74 int parsed = git_config_int(value, value, ctx->kvi);
75 printf("%d\n", parsed);
76 }
77 return 0;
78 }
79
80 static int early_config_cb(const char *var, const char *value,
81 const struct config_context *ctx UNUSED,
82 void *vdata)
83 {
84 const char *key = vdata;
85
86 if (!strcmp(key, var))
87 printf("%s\n", value);
88
89 return 0;
90 }
91
92 int cmd__config(int argc, const char **argv)
93 {
94 int i, val;
95 const char *v;
96 const struct string_list *strptr;
97 struct config_set cs;
98
99 if (argc == 3 && !strcmp(argv[1], "read_early_config")) {
100 read_early_config(the_repository, early_config_cb,
101 (void *)argv[2]);
102 return 0;
103 }
104
105 setup_git_directory(the_repository);
106
107 git_configset_init(&cs);
108
109 if (argc < 2) {
110 fprintf(stderr, "Please, provide a command name on the command-line\n");
111 goto exit1;
112 } else if (argc == 3 && !strcmp(argv[1], "get_value")) {
113 if (!repo_config_get_value(the_repository, argv[2], &v)) {
114 if (!v)
115 printf("(NULL)\n");
116 else
117 printf("%s\n", v);
118 goto exit0;
119 } else {
120 printf("Value not found for \"%s\"\n", argv[2]);
121 goto exit1;
122 }
123 } else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) {
124 if (!repo_config_get_value_multi(the_repository, argv[2], &strptr)) {
125 for (i = 0; i < strptr->nr; i++) {
126 v = strptr->items[i].string;
127 if (!v)
128 printf("(NULL)\n");
129 else
130 printf("%s\n", v);
131 }
132 goto exit0;
133 } else {
134 printf("Value not found for \"%s\"\n", argv[2]);
135 goto exit1;
136 }
137 } else if (argc == 3 && !strcmp(argv[1], "get")) {
138 int ret;
139
140 if (!(ret = repo_config_get(the_repository, argv[2])))
141 goto exit0;
142 else if (ret == 1)
143 printf("Value not found for \"%s\"\n", argv[2]);
144 else if (ret == -CONFIG_INVALID_KEY)
145 printf("Key \"%s\" is invalid\n", argv[2]);
146 else if (ret == -CONFIG_NO_SECTION_OR_NAME)
147 printf("Key \"%s\" has no section\n", argv[2]);
148 else
149 /*
150 * A normal caller should just check "ret <
151 * 0", but for our own tests let's BUG() if
152 * our whitelist of git_config_parse_key()
153 * return values isn't exhaustive.
154 */
155 BUG("Key \"%s\" has unknown return %d", argv[2], ret);
156 goto exit1;
157 } else if (argc == 3 && !strcmp(argv[1], "get_int")) {
158 if (!repo_config_get_int(the_repository, argv[2], &val)) {
159 printf("%d\n", val);
160 goto exit0;
161 } else {
162 printf("Value not found for \"%s\"\n", argv[2]);
163 goto exit1;
164 }
165 } else if (argc == 3 && !strcmp(argv[1], "get_bool")) {
166 if (!repo_config_get_bool(the_repository, argv[2], &val)) {
167 printf("%d\n", val);
168 goto exit0;
169 } else {
170 printf("Value not found for \"%s\"\n", argv[2]);
171 goto exit1;
172 }
173 } else if (argc == 3 && !strcmp(argv[1], "get_string")) {
174 if (!repo_config_get_string_tmp(the_repository, argv[2], &v)) {
175 printf("%s\n", v);
176 goto exit0;
177 } else {
178 printf("Value not found for \"%s\"\n", argv[2]);
179 goto exit1;
180 }
181 } else if (!strcmp(argv[1], "configset_get_value")) {
182 for (i = 3; i < argc; i++) {
183 int err;
184 if ((err = git_configset_add_file(&cs, argv[i]))) {
185 fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]);
186 goto exit2;
187 }
188 }
189 if (!git_configset_get_value(&cs, argv[2], &v, NULL)) {
190 if (!v)
191 printf("(NULL)\n");
192 else
193 printf("%s\n", v);
194 goto exit0;
195 } else {
196 printf("Value not found for \"%s\"\n", argv[2]);
197 goto exit1;
198 }
199 } else if (!strcmp(argv[1], "configset_get_value_multi")) {
200 for (i = 3; i < argc; i++) {
201 int err;
202 if ((err = git_configset_add_file(&cs, argv[i]))) {
203 fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]);
204 goto exit2;
205 }
206 }
207 if (!git_configset_get_value_multi(&cs, argv[2], &strptr)) {
208 for (i = 0; i < strptr->nr; i++) {
209 v = strptr->items[i].string;
210 if (!v)
211 printf("(NULL)\n");
212 else
213 printf("%s\n", v);
214 }
215 goto exit0;
216 } else {
217 printf("Value not found for \"%s\"\n", argv[2]);
218 goto exit1;
219 }
220 } else if (!strcmp(argv[1], "iterate")) {
221 repo_config(the_repository, iterate_cb, NULL);
222 goto exit0;
223 } else if (argc == 3 && !strcmp(argv[1], "git_config_int")) {
224 repo_config(the_repository, parse_int_cb, (void *) argv[2]);
225 goto exit0;
226 }
227
228 die("%s: Please check the syntax and the function name", argv[0]);
229
230 exit0:
231 git_configset_clear(&cs);
232 return 0;
233
234 exit1:
235 git_configset_clear(&cs);
236 return 1;
237
238 exit2:
239 git_configset_clear(&cs);
240 return 2;
241 }