git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Eli Barzilay" <eli@barzilay.org>,
	"Heiko Voigt" <hvoigt@hvoigt.net>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH/RFC] Hacky version of a glob() driven config include
Date: Thu,  6 May 2010 21:14:00 +0000	[thread overview]
Message-ID: <1273180440-8641-1-git-send-email-avarab@gmail.com> (raw)
In-Reply-To: <u2i51dd1af81004060115t5f837840z5adcf83622fa8882@mail.gmail.com>

This is not ready for inclusion in anything. Commiting for RFC on
whether this way of doing it is sane in theory.

Known bugs:

  * Breaks the model of being able to *set* config values. That
    doesn't work for the included files. Maybe not a bug.

  * Errors in the git_config_from_file() call in glob_include_config()
    aren't passed upwards.

  * It relies on the GNU GLOB_TILDE extension with no
    alternative. That can be done by calling getenv("HOME") and
    s/~/$home/.

  * The whole bit with saving/restoring global state for config
    inclusion is evil, but then again so is the global state.

  * We don't check for recursion. But Git gives up eventually after
    after spewing a *lot* of duplicate entry errors. Not sure how to
    do this sanely w/symlinks.

Not-signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---

> On Sun, Apr 4, 2010 at 07:50, Eli Barzilay <eli@barzilay.org> wrote:
> > Isn't it better to have a way to include files instead?
>
> Probably yes. Programs like Apache HTTPD, rsyslog and others just use
> ${foo}conf.d by convention by supporting config inclusion.

Here's an evil implementation of this. I know the code is horrid &
buggy (see above). But is the general idea sane. I thought it would be
better to submit this for comments before I went further with it.

 config.c               |   55 +++++++++++++++++++++++++++++++++++++++++++++++-
 t/t1300-repo-config.sh |   43 +++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 1 deletions(-)

diff --git a/config.c b/config.c
index 6963fbe..e7581b4 100644
--- a/config.c
+++ b/config.c
@@ -7,6 +7,7 @@
  */
 #include "cache.h"
 #include "exec_cmd.h"
+#include <glob.h>
 
 #define MAXNAME (256)
 
@@ -111,6 +112,52 @@ static inline int iskeychar(int c)
 	return isalnum(c) || c == '-';
 }
 
+static void glob_include_config(config_fn_t fn, void *data, char *pattern)
+{
+	glob_t globber;
+	int glob_ret;
+	int conf_ret;
+	size_t i = 0;
+	char *cfile = NULL;
+	FILE *saved_config_file;
+	char *saved_config_file_name;
+	int saved_config_linenr;
+	int saved_config_file_eof;
+#ifdef GLOB_TILDE
+	int glob_flags = GLOB_TILDE;
+#else
+	/* XXX: Non-GNU support for ~ expansion */
+	int glob_flags = 0;
+#endif
+
+	glob_ret = glob(pattern, glob_flags, NULL, &globber);
+
+	if (glob_ret == GLOB_NOSPACE || glob_ret == GLOB_ABORTED) {
+		globfree(&globber);
+		die("Unable to include config with pattern %s", pattern);
+	}
+
+	for (i = 0; i < globber.gl_pathc; i++) {
+		cfile = globber.gl_pathv[i];
+
+		/* Save away global state for including another file */
+		saved_config_file = config_file;
+		saved_config_file_name = config_file_name;
+		saved_config_linenr = config_linenr;
+		saved_config_file_eof = config_file_eof;
+
+		conf_ret = git_config_from_file(fn, cfile, data);
+
+		/* Restore it again */
+		config_file = saved_config_file;
+		config_file_name = saved_config_file_name;
+		config_linenr = saved_config_linenr;
+		config_file_eof = saved_config_file_eof;
+	}
+
+	globfree(&globber);
+}
+
 static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
 {
 	int c;
@@ -139,7 +186,13 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
 		if (!value)
 			return -1;
 	}
-	return fn(name, value, data);
+
+	if (!strcmp(name, "voodoo.include")) {
+		glob_include_config(fn, data, value);
+		return 0;
+	} else {
+		return fn(name, value, data);
+	}
 }
 
 static int get_extended_base_var(char *name, int baselen, int c)
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index f11f98c..4df6658 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -824,4 +824,47 @@ test_expect_success 'check split_cmdline return' "
 	test_must_fail git merge master
 	"
 
+cat > .git/config << EOF
+[some]
+	variable = blah
+[voodoo]
+	include = .git/more_config_*
+EOF
+
+cat > .git/more_config_1 << EOF
+[another]
+	variable = blah blah
+EOF
+
+cat > .git/more_config_2 << EOF
+[evenmore]
+	variable = blah bluh 
+EOF
+
+test_expect_success 'The voodoo include variable is hidden from us' \
+    'test_must_fail git config --get voodoo.include'
+test_expect_success 'get some included variable' \
+    'git config --get some.variable'
+test_expect_success 'get another included variable' \
+    'git config --get another.variable'
+test_expect_success 'get evenmore included variable' \
+    'git config --get evenmore.variable'
+
+rm .git/more_config*
+
+cat > .git/config << EOF
+[voodoo]
+	include = .git/more_config_*
+EOF
+
+cat > .git/more_config_1 << EOF
+[foo]
+    bar = zar
+[voodoo]
+	include = .git/more_config_*
+EOF
+
+test_expect_success 'circular config inclusion' \
+    'test_must_fail git config --get foo.bar'
+
 test_done
-- 
1.7.1.dirty

  parent reply	other threads:[~2010-05-06 21:14 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-01 21:20 Is there interest in reading ~/.gitconfig.d/* and /etc/gitconfig.d/*? Ævar Arnfjörð Bjarmason
2010-04-01 22:03 ` Heiko Voigt
2010-04-04  7:24 ` Peter Krefting
2010-04-04  7:59   ` Eli Barzilay
     [not found]   ` <19384.17579.205005.86711@winooski.ccs.neu.edu>
2010-04-06  8:15     ` Ævar Arnfjörð Bjarmason
2010-04-06  9:02       ` Jakub Narebski
2010-05-06 21:14       ` Ævar Arnfjörð Bjarmason [this message]
2010-05-07  6:00         ` [PATCH/RFC] Hacky version of a glob() driven config include Bert Wesarg
2010-05-07 16:56           ` Ævar Arnfjörð Bjarmason
2010-05-07 18:29             ` Bert Wesarg
2010-05-07 18:58               ` Ævar Arnfjörð Bjarmason
2010-05-07 19:02                 ` Jacob Helwig
2010-05-07 19:52                 ` Bert Wesarg
2010-05-07 20:11                   ` [PATCH/RFC v2] " Ævar Arnfjörð Bjarmason
2010-05-07 20:46         ` [PATCH/RFC] " Jakub Narebski
2010-05-07 22:15           ` Ævar Arnfjörð Bjarmason
2010-05-07 23:43             ` Jakub Narebski
2010-05-08  2:30               ` Ping Yin
2010-05-08  8:18                 ` Jakub Narebski
2010-05-08  9:03                   ` Ping Yin
2010-05-08  5:06         ` Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1273180440-8641-1-git-send-email-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=eli@barzilay.org \
    --cc=git@vger.kernel.org \
    --cc=hvoigt@hvoigt.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).