Re: Re: [PATCH v2 4/4] teach config parsing to read from strbuf
Hi Peff, On Thu, Mar 14, 2013 at 03:39:14AM -0400, Jeff King wrote: On Thu, Mar 14, 2013 at 03:10:46AM -0400, Jeff King wrote: I looked into this a little. The first sticking point is that git_config_with_options needs to support the alternate source. Here's a sketch of what I think the solution should look like, on top of your patches. Here it is again, with two changes: 1. Rather than handling the blob lookup inline in git_config_with_options, it adds direct functions for reading config from blob sha1s and blob references. I think this should make it easier to reuse when you are trying to read .gitmodules from C code. 2. It adds some basic tests. I'll leave it here for tonight. The next step would be to rebase it on your modified series (in particular, I think git_config_from_strbuf should become git_config_from_buf, which will impact this). Feel free to use, pick apart, rewrite, or discard as you see fit for your series. Sorry for the late reply, I was not online during the last days. Thanks a lot for this. I will use it in the next iteration of the series. Cheers Heiko -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/4] teach config parsing to read from strbuf
On Tue, Mar 12, 2013 at 03:29:59PM -0400, Jeff King wrote: On Tue, Mar 12, 2013 at 05:42:54PM +0100, Heiko Voigt wrote: Your series does not actually add any callers of the new function. The obvious patch 5/4 would be to plumb it into git config --blob, and then we can just directly test it there (there could be other callers besides reading from a blob, of course, but I think the point of the series is to head in that direction). Since this is a split of the series mentioned above there are no real callers yet. The main reason for the split was that I wanted to reduce the review burden of one big series into multiple reviews of smaller chunks. If you think it is useful to add the --blob option I can also test from there. It could actually be useful to look at certain .gitmodules options from the submodule script. I am on the fence. I do not want to create more work for you, but I do think it may come in handy, if only for doing submodule things from shell. And it is hopefully not a very large patch. I'd say try it, and if starts looking like it will be very ugly, the right thing may be to leave it until somebody really wants it. Thats what I will do: Try it and see where I get. Cheers Heiko -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/4] teach config parsing to read from strbuf
On Thu, Mar 14, 2013 at 07:39:33AM +0100, Heiko Voigt wrote: I am on the fence. I do not want to create more work for you, but I do think it may come in handy, if only for doing submodule things from shell. And it is hopefully not a very large patch. I'd say try it, and if starts looking like it will be very ugly, the right thing may be to leave it until somebody really wants it. Thats what I will do: Try it and see where I get. I looked into this a little. The first sticking point is that git_config_with_options needs to support the alternate source. Here's a sketch of what I think the solution should look like, on top of your patches. diff --git a/builtin/config.c b/builtin/config.c index 33c9bf9..8d01b7a 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -21,6 +21,7 @@ static const char *given_config_file; static int use_global_config, use_system_config, use_local_config; static const char *given_config_file; +static const char *given_config_blob; static int actions, types; static const char *get_color_slot, *get_colorbool_slot; static int end_null; @@ -53,6 +54,7 @@ static struct option builtin_config_options[] = { OPT_BOOLEAN(0, system, use_system_config, N_(use system config file)), OPT_BOOLEAN(0, local, use_local_config, N_(use repository config file)), OPT_STRING('f', file, given_config_file, N_(file), N_(use given config file)), + OPT_STRING(0, blob, given_config_blob, N_(blob-id), N_(read config from given blob object)), OPT_GROUP(N_(Action)), OPT_BIT(0, get, actions, N_(get value: name [value-regex]), ACTION_GET), OPT_BIT(0, get-all, actions, N_(get all values: key [value-regex]), ACTION_GET_ALL), @@ -218,7 +220,8 @@ static int get_value(const char *key_, const char *regex_) } git_config_with_options(collect_config, values, - given_config_file, respect_includes); + given_config_file, given_config_blob, + respect_includes); ret = !values.nr; @@ -302,7 +305,8 @@ static void get_color(const char *def_color) get_color_found = 0; parsed_color[0] = '\0'; git_config_with_options(git_get_color_config, NULL, - given_config_file, respect_includes); + given_config_file, given_config_blob, + respect_includes); if (!get_color_found def_color) color_parse(def_color, command line, parsed_color); @@ -330,7 +334,8 @@ static int get_colorbool(int print) get_colorbool_found = -1; get_diff_color_found = -1; git_config_with_options(git_get_colorbool_config, NULL, - given_config_file, respect_includes); + given_config_file, given_config_blob, + respect_includes); if (get_colorbool_found 0) { if (!strcmp(get_colorbool_slot, color.diff)) @@ -348,6 +353,12 @@ static int get_colorbool(int print) return get_colorbool_found ? 0 : 1; } +static void check_blob_write(void) +{ + if (given_config_blob) + die(writing config blobs is not supported); +} + int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = !startup_info-have_repository; @@ -359,7 +370,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) builtin_config_usage, PARSE_OPT_STOP_AT_NON_OPTION); - if (use_global_config + use_system_config + use_local_config + !!given_config_file 1) { + if (use_global_config + use_system_config + use_local_config + + !!given_config_file + !!given_config_blob 1) { error(only one config file at a time.); usage_with_options(builtin_config_usage, builtin_config_options); } @@ -438,6 +450,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 0, 0); if (git_config_with_options(show_all_config, NULL, given_config_file, + given_config_blob, respect_includes) 0) { if (given_config_file) die_errno(unable to read config file '%s', @@ -450,6 +463,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 0, 0); if (!given_config_file nongit) die(not in a git directory); + if (given_config_blob) + die(editing blobs is not supported); git_config(git_default_config, NULL); launch_editor(given_config_file ? given_config_file :
Re: [PATCH v2 4/4] teach config parsing to read from strbuf
On Thu, Mar 14, 2013 at 03:10:46AM -0400, Jeff King wrote: I looked into this a little. The first sticking point is that git_config_with_options needs to support the alternate source. Here's a sketch of what I think the solution should look like, on top of your patches. Here it is again, with two changes: 1. Rather than handling the blob lookup inline in git_config_with_options, it adds direct functions for reading config from blob sha1s and blob references. I think this should make it easier to reuse when you are trying to read .gitmodules from C code. 2. It adds some basic tests. I'll leave it here for tonight. The next step would be to rebase it on your modified series (in particular, I think git_config_from_strbuf should become git_config_from_buf, which will impact this). Feel free to use, pick apart, rewrite, or discard as you see fit for your series. diff --git a/builtin/config.c b/builtin/config.c index 33c9bf9..8d01b7a 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -21,6 +21,7 @@ static const char *given_config_file; static int use_global_config, use_system_config, use_local_config; static const char *given_config_file; +static const char *given_config_blob; static int actions, types; static const char *get_color_slot, *get_colorbool_slot; static int end_null; @@ -53,6 +54,7 @@ static struct option builtin_config_options[] = { OPT_BOOLEAN(0, system, use_system_config, N_(use system config file)), OPT_BOOLEAN(0, local, use_local_config, N_(use repository config file)), OPT_STRING('f', file, given_config_file, N_(file), N_(use given config file)), + OPT_STRING(0, blob, given_config_blob, N_(blob-id), N_(read config from given blob object)), OPT_GROUP(N_(Action)), OPT_BIT(0, get, actions, N_(get value: name [value-regex]), ACTION_GET), OPT_BIT(0, get-all, actions, N_(get all values: key [value-regex]), ACTION_GET_ALL), @@ -218,7 +220,8 @@ static int get_value(const char *key_, const char *regex_) } git_config_with_options(collect_config, values, - given_config_file, respect_includes); + given_config_file, given_config_blob, + respect_includes); ret = !values.nr; @@ -302,7 +305,8 @@ static void get_color(const char *def_color) get_color_found = 0; parsed_color[0] = '\0'; git_config_with_options(git_get_color_config, NULL, - given_config_file, respect_includes); + given_config_file, given_config_blob, + respect_includes); if (!get_color_found def_color) color_parse(def_color, command line, parsed_color); @@ -330,7 +334,8 @@ static int get_colorbool(int print) get_colorbool_found = -1; get_diff_color_found = -1; git_config_with_options(git_get_colorbool_config, NULL, - given_config_file, respect_includes); + given_config_file, given_config_blob, + respect_includes); if (get_colorbool_found 0) { if (!strcmp(get_colorbool_slot, color.diff)) @@ -348,6 +353,12 @@ static int get_colorbool(int print) return get_colorbool_found ? 0 : 1; } +static void check_blob_write(void) +{ + if (given_config_blob) + die(writing config blobs is not supported); +} + int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = !startup_info-have_repository; @@ -359,7 +370,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) builtin_config_usage, PARSE_OPT_STOP_AT_NON_OPTION); - if (use_global_config + use_system_config + use_local_config + !!given_config_file 1) { + if (use_global_config + use_system_config + use_local_config + + !!given_config_file + !!given_config_blob 1) { error(only one config file at a time.); usage_with_options(builtin_config_usage, builtin_config_options); } @@ -438,6 +450,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 0, 0); if (git_config_with_options(show_all_config, NULL, given_config_file, + given_config_blob, respect_includes) 0) { if (given_config_file) die_errno(unable to read config file '%s', @@ -450,6 +463,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 0, 0); if (!given_config_file nongit) die(not in a git directory); +
Re: [PATCH v2 4/4] teach config parsing to read from strbuf
On Tue, Mar 12, 2013 at 07:18:06AM -0400, Jeff King wrote: On Sun, Mar 10, 2013 at 06:00:52PM +0100, Heiko Voigt wrote: This can be used to read configuration values directly from gits database. Signed-off-by: Heiko Voigt hvo...@hvoigt.net This is lacking motivation. IIRC, the rest of the story is something like ...so we can read .gitmodules directly from the repo or something like that? Will add some more here. +struct config_strbuf { + struct strbuf *strbuf; + int pos; +}; +static int config_strbuf_fgetc(struct config_source *conf) +{ + struct config_strbuf *str = conf-data; Yuck. If you used a union in the previous patch, then this could just go inline into the struct config_source. +int git_config_from_strbuf(config_fn_t fn, const char *name, struct strbuf *strbuf, void *data) Should this be a const struct strbuf *strbuf? For that matter, is there any reason not to take a bare pointer/len combination? It seems likely that callers would get the data from read_sha1_file, which means they have to stuff it into a strbuf for no good reason. pointer/len should be fine too. I just used strbuf since when you find out later that you need to modify the string its easier to handle. A config parser should not need to do that so I will change that. diff --git a/test-config.c b/test-config.c new file mode 100644 index 000..c650837 --- /dev/null +++ b/test-config.c @@ -0,0 +1,40 @@ I'm slightly meh on this test-config program. Having to add a C test harness like this is a good indication that we are short-changing users of the shell API in favor of builtin C code. I mainly did this because I needed some test for the config part while developing the fetch renamed submodules series. Your series does not actually add any callers of the new function. The obvious patch 5/4 would be to plumb it into git config --blob, and then we can just directly test it there (there could be other callers besides reading from a blob, of course, but I think the point of the series is to head in that direction). Since this is a split of the series mentioned above there are no real callers yet. The main reason for the split was that I wanted to reduce the review burden of one big series into multiple reviews of smaller chunks. If you think it is useful to add the --blob option I can also test from there. It could actually be useful to look at certain .gitmodules options from the submodule script. Cheers Heiko -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/4] teach config parsing to read from strbuf
On Tue, Mar 12, 2013 at 05:42:54PM +0100, Heiko Voigt wrote: Your series does not actually add any callers of the new function. The obvious patch 5/4 would be to plumb it into git config --blob, and then we can just directly test it there (there could be other callers besides reading from a blob, of course, but I think the point of the series is to head in that direction). Since this is a split of the series mentioned above there are no real callers yet. The main reason for the split was that I wanted to reduce the review burden of one big series into multiple reviews of smaller chunks. If you think it is useful to add the --blob option I can also test from there. It could actually be useful to look at certain .gitmodules options from the submodule script. I am on the fence. I do not want to create more work for you, but I do think it may come in handy, if only for doing submodule things from shell. And it is hopefully not a very large patch. I'd say try it, and if starts looking like it will be very ugly, the right thing may be to leave it until somebody really wants it. -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/4] teach config parsing to read from strbuf
This can be used to read configuration values directly from gits database. Signed-off-by: Heiko Voigt hvo...@hvoigt.net --- .gitignore | 1 + Makefile | 1 + cache.h| 2 ++ config.c | 48 t/t1300-repo-config.sh | 24 test-config.c | 40 6 files changed, 116 insertions(+) create mode 100644 test-config.c diff --git a/.gitignore b/.gitignore index 6669bf0..386b7f2 100644 --- a/.gitignore +++ b/.gitignore @@ -178,6 +178,7 @@ /gitweb/static/gitweb.min.* /test-chmtime /test-ctype +/test-config /test-date /test-delta /test-dump-cache-tree diff --git a/Makefile b/Makefile index 26d3332..1a9ea10 100644 --- a/Makefile +++ b/Makefile @@ -541,6 +541,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS)) TEST_PROGRAMS_NEED_X += test-chmtime TEST_PROGRAMS_NEED_X += test-ctype +TEST_PROGRAMS_NEED_X += test-config TEST_PROGRAMS_NEED_X += test-date TEST_PROGRAMS_NEED_X += test-delta TEST_PROGRAMS_NEED_X += test-dump-cache-tree diff --git a/cache.h b/cache.h index e493563..a2621fa 100644 --- a/cache.h +++ b/cache.h @@ -1128,6 +1128,8 @@ extern int update_server_info(int); typedef int (*config_fn_t)(const char *, const char *, void *); extern int git_default_config(const char *, const char *, void *); extern int git_config_from_file(config_fn_t fn, const char *, void *); +extern int git_config_from_strbuf(config_fn_t fn, const char *name, + struct strbuf *strbuf, void *data); extern void git_config_push_parameter(const char *text); extern int git_config_from_parameters(config_fn_t fn, void *data); extern int git_config(config_fn_t fn, void *); diff --git a/config.c b/config.c index fe1c0e5..b8c8640 100644 --- a/config.c +++ b/config.c @@ -46,6 +46,37 @@ static long config_file_ftell(struct config_source *conf) return ftell(f); } +struct config_strbuf { + struct strbuf *strbuf; + int pos; +}; + +static int config_strbuf_fgetc(struct config_source *conf) +{ + struct config_strbuf *str = conf-data; + + if (str-pos str-strbuf-len) + return str-strbuf-buf[str-pos++]; + + return EOF; +} + +static int config_strbuf_ungetc(int c, struct config_source *conf) +{ + struct config_strbuf *str = conf-data; + + if (str-pos 0) + return str-strbuf-buf[--str-pos]; + + return EOF; +} + +static long config_strbuf_ftell(struct config_source *conf) +{ + struct config_strbuf *str = conf-data; + return str-pos; +} + #define MAX_INCLUDE_DEPTH 10 static const char include_depth_advice[] = exceeded maximum include depth (%d) while including\n @@ -961,6 +992,23 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data) return ret; } +int git_config_from_strbuf(config_fn_t fn, const char *name, struct strbuf *strbuf, void *data) +{ + struct config_source top; + struct config_strbuf str; + + str.strbuf = strbuf; + str.pos = 0; + + top.data = str; + top.name = name; + top.fgetc = config_strbuf_fgetc; + top.ungetc = config_strbuf_ungetc; + top.ftell = config_strbuf_ftell; + + return do_config_from_source(top, fn, data); +} + const char *git_etc_gitconfig(void) { static const char *system_wide; diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 3c96fda..5103f66 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -1087,4 +1087,28 @@ test_expect_success 'barf on incomplete string' ' grep line 3 error ' +test_expect_success 'reading config from strbuf' ' + cat expect -\EOF + var: some.value, value: content + EOF + test-config strbuf 12345:.gitmodules actual -\EOF + [some] + value = content + EOF + test_cmp expect actual +' + +test_expect_success 'reading config from strbuf with error' ' + touch expect.out + cat expect.err -\EOF + fatal: bad config file line 2 in 12345:.gitmodules + EOF + test_must_fail test-config strbuf 12345:.gitmodules actual.out 2actual.err -\EOF + [some] + value = + EOF + test_cmp expect.out actual.out + test_cmp expect.err actual.err +' + test_done diff --git a/test-config.c b/test-config.c new file mode 100644 index 000..c650837 --- /dev/null +++ b/test-config.c @@ -0,0 +1,40 @@ +#include cache.h + +static int config_strbuf(const char *var, const char *value, void *data) +{ + printf(var: %s, value: %s\n, var, value); + + return 1; +} + +static void die_usage(int argc, char **argv) +{ + fprintf(stderr, Usage: %s strbuf name\n, argv[0]); + exit(1); +} + +int main(int argc, char **argv) +{ + if (argc 3) + die_usage(argc, argv); + + if (!strcmp(argv[1], strbuf)) { +