summaryrefslogtreecommitdiff
path: root/src/attr.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-03-15 16:39:00 -0700
committerRussell Belfer <rb@github.com>2013-03-15 16:39:00 -0700
commit5540d9477ed143707435324e785336d254b12e47 (patch)
tree4ffaba1990a82cc51ee5169d7d2913ecceef4df2 /src/attr.c
parenta5f6138407efb6d8866fe8de5aac13454aefcd82 (diff)
downloadlibgit2-5540d9477ed143707435324e785336d254b12e47.tar.gz
Implement global/system file search paths
The goal of this work is to expose the search logic for "global", "system", and "xdg" files through the git_libgit2_opts() interface. Behind the scenes, I changed the logic for finding files to have a notion of a git_strarray that represents a search path and to store a separate search path for each of the three tiers of config file. For each tier, I implemented a function to initialize it to default values (generally based on environment variables), and then general interfaces to get it, set it, reset it, and prepend new directories to it. Next, I exposed these interfaces through the git_libgit2_opts interface, reusing the GIT_CONFIG_LEVEL_SYSTEM, etc., constants for the user to control which search path they were modifying. There are alternative designs for the opts interface / argument ordering, so I'm putting this phase out for discussion. Additionally, I ended up doing a little bit of clean up regarding attr.h and attr_file.h, adding a new attrcache.h so the other two files wouldn't have to be included in so many places.
Diffstat (limited to 'src/attr.c')
-rw-r--r--src/attr.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/attr.c b/src/attr.c
index 9c88771e3..979fecc14 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -1,6 +1,8 @@
#include "repository.h"
#include "fileops.h"
#include "config.h"
+#include "attr.h"
+#include "ignore.h"
#include "git2/oid.h"
#include <ctype.h>
@@ -593,17 +595,28 @@ static int collect_attr_files(
return error;
}
-static char *try_global_default(const char *relpath)
+static int attr_cache__lookup_path(
+ const char **out, git_config *cfg, const char *key, const char *fallback)
{
- git_buf dflt = GIT_BUF_INIT;
- char *rval = NULL;
+ git_buf buf = GIT_BUF_INIT;
+ int error;
- if (!git_futils_find_global_file(&dflt, relpath))
- rval = git_buf_detach(&dflt);
+ if (!(error = git_config_get_string(out, cfg, key)))
+ return 0;
- git_buf_free(&dflt);
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
+ error = 0;
- return rval;
+ if (!git_futils_find_xdg_file(&buf, fallback))
+ *out = git_buf_detach(&buf);
+ else
+ *out = NULL;
+
+ git_buf_free(&buf);
+ }
+
+ return error;
}
int git_attr_cache__init(git_repository *repo)
@@ -619,19 +632,15 @@ int git_attr_cache__init(git_repository *repo)
if (git_repository_config__weakptr(&cfg, repo) < 0)
return -1;
- ret = git_config_get_string(&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG);
- if (ret < 0 && ret != GIT_ENOTFOUND)
+ ret = attr_cache__lookup_path(
+ &cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG, GIT_ATTR_FILE_XDG);
+ if (ret < 0)
return ret;
- if (ret == GIT_ENOTFOUND)
- cache->cfg_attr_file = try_global_default(GIT_ATTR_CONFIG_DEFAULT);
- ret = git_config_get_string(&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG);
- if (ret < 0 && ret != GIT_ENOTFOUND)
+ ret = attr_cache__lookup_path(
+ &cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG, GIT_IGNORE_FILE_XDG);
+ if (ret < 0)
return ret;
- if (ret == GIT_ENOTFOUND)
- cache->cfg_excl_file = try_global_default(GIT_IGNORE_CONFIG_DEFAULT);
-
- giterr_clear();
/* allocate hashtable for attribute and ignore file contents */
if (cache->files == NULL) {