builtin/config: introduce `color` type specifier
As of this commit, the canonical way to retreive an ANSI-compatible color escape sequence from a configuration file is with the `--get-color` action. This is to allow Git to "fall back" on a default value for the color should the given section not exist in the specified configuration(s). With the addition of `--default`, this is no longer needed since: $ git config --default red --type=color core.section will be have exactly as: $ git config --get-color core.section red For consistency, let's introduce `--type=color` and encourage its use with `--default` together over `--get-color` alone. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
Apr 9, 2018 at 17:18 UTC
63e2a0f8e9cc3d66137a72e424a8b59f1c4dbd79
3 files changed
+58
Documentation/git-config.txt
+6
@@ -177,6 +177,10 @@ Valid `<type>`'s include:
177
~/` from the command line to let your shell do the expansion.)
178
- 'expiry-date': canonicalize by converting from a fixed or relative date-string
179
to a timestamp. This specifier has no effect when setting the value.
180
+- 'color': When getting a value, canonicalize by converting to an ANSI color
181
+ escape sequence. When setting a value, a sanity-check is performed to ensure
182
+ that the given value is canonicalize-able as an ANSI color, but it is written
183
+ as-is.
184
+
185
186
--bool::
@@ -228,6 +232,8 @@ Valid `<type>`'s include:
232
output it as the ANSI color escape sequence to the standard
233
output. The optional `default` parameter is used instead, if
234
there is no color configured for `name`.
235
++
236
+`--type=color [--default=<default>]` is preferred over `--get-color`.
237
238
-e::
239
--edit::
builtin/config.c
+22
@@ -61,6 +61,7 @@ static int show_origin;
61
#define TYPE_BOOL_OR_INT 3
62
#define TYPE_PATH 4
63
#define TYPE_EXPIRY_DATE 5
64
+#define TYPE_COLOR 6
65
66
#define OPT_CALLBACK_VALUE(s, l, v, h, i) \
67
{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
95
new_type = TYPE_PATH;
96
else if (!strcmp(arg, "expiry-date"))
97
new_type = TYPE_EXPIRY_DATE;
98
+ else if (!strcmp(arg, "color"))
99
+ new_type = TYPE_COLOR;
100
else
101
die(_("unrecognized --type argument, %s"), arg);
102
}
@@ -230,6 +233,11 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
233
if (git_config_expiry_date(&t, key_, value_) < 0)
234
return -1;
235
strbuf_addf(buf, "%"PRItime, t);
236
+ } else if (type == TYPE_COLOR) {
237
+ char v[COLOR_MAXLEN];
238
+ if (git_config_color(v, key_, value_) < 0)
239
+ return -1;
240
+ strbuf_addstr(buf, v);
241
} else if (value_) {
242
strbuf_addstr(buf, value_);
243
} else {
@@ -375,6 +383,20 @@ static char *normalize_value(const char *key, const char *value)
383
else
384
return xstrdup(v ? "true" : "false");
385
}
386
+ if (type == TYPE_COLOR) {
387
+ char v[COLOR_MAXLEN];
388
+ if (git_config_color(v, key, value))
389
+ die("cannot parse color '%s'", value);
390
+
391
+ /*
392
+ * The contents of `v` now contain an ANSI escape
393
+ * sequence, not suitable for including within a
394
+ * configuration file. Treat the above as a
395
+ * "sanity-check", and return the given value, which we
396
+ * know is representable as valid color code.
397
+ */
398
+ return xstrdup(value);
399
+ }
400
401
die("BUG: cannot normalize type %d", type);
402
}
t/t1300-repo-config.sh
+30
@@ -931,6 +931,36 @@ test_expect_success 'get --expiry-date' '
931
test_must_fail git config --expiry-date date.invalid1
932
'
933
934
+test_expect_success 'get --type=color' '
935
+ rm .git/config &&
936
+ git config foo.color "red" &&
937
+ git config --get --type=color foo.color >actual.raw &&
938
+ test_decode_color <actual.raw >actual &&
939
+ echo "<RED>" >expect &&
940
+ test_cmp expect actual
941
+'
942
+
943
+cat >expect << EOF
944
+[foo]
945
+ color = red
946
+EOF
947
+
948
+test_expect_success 'set --type=color' '
949
+ rm .git/config &&
950
+ git config --type=color foo.color "red" &&
951
+ test_cmp expect .git/config
952
+'
953
+
954
+test_expect_success 'get --type=color barfs on non-color' '
955
+ echo "[foo]bar=not-a-color" >.git/config &&
956
+ test_must_fail git config --get --type=color foo.bar
957
+'
958
+
959
+test_expect_success 'set --type=color barfs on non-color' '
960
+ test_must_fail git config --type=color foo.color "not-a-color" 2>error &&
961
+ test_i18ngrep "cannot parse color" error
962
+'
963
+
964
cat > expect << EOF
965
[quote]
966
leading = " test"