diff options
author | nulltoken <emeric.fermas@gmail.com> | 2012-11-17 13:39:24 -0800 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2012-11-17 18:30:34 -0800 |
commit | 270160b91a0e55486f2cb6a6238c39fcd1271809 (patch) | |
tree | 9ba94cc336c12c29955324b1d3572869154aab94 | |
parent | d36451c9d4ba071de07106371553bf93f2717fc4 (diff) | |
download | libgit2-270160b91a0e55486f2cb6a6238c39fcd1271809.tar.gz |
config: Opening a nonexistent file returns ENOTFOUND
-rw-r--r-- | include/git2/config.h | 11 | ||||
-rw-r--r-- | src/config.c | 26 | ||||
-rw-r--r-- | src/repository.c | 23 | ||||
-rw-r--r-- | tests-clar/config/new.c | 1 | ||||
-rw-r--r-- | tests-clar/config/read.c | 20 |
5 files changed, 69 insertions, 12 deletions
diff --git a/include/git2/config.h b/include/git2/config.h index 8270aefa4..8ec78e35c 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -189,7 +189,8 @@ GIT_EXTERN(int) git_config_add_file( * @param force if a config file already exists for the given * priority level, replace it * @return 0 on success, GIT_EEXISTS when adding more than one file - * for a given priority level (and force_replace set to 0), or error code + * for a given priority level (and force_replace set to 0), + * GIT_ENOTFOUND when the file doesn't exist or error code */ GIT_EXTERN(int) git_config_add_file_ondisk( git_config *cfg, @@ -197,7 +198,6 @@ GIT_EXTERN(int) git_config_add_file_ondisk( unsigned int level, int force); - /** * Create a new config instance containing a single on-disk file * @@ -206,11 +206,12 @@ GIT_EXTERN(int) git_config_add_file_ondisk( * - git_config_new * - git_config_add_file_ondisk * - * @param cfg The configuration instance to create + * @param out The configuration instance to create * @param path Path to the on-disk file to open - * @return 0 or an error code + * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist + * or an error code */ -GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path); +GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path); /** * Build a single-level focused config object from a multi-level one. diff --git a/src/config.c b/src/config.c index 01a54ecf2..412965b73 100644 --- a/src/config.c +++ b/src/config.c @@ -90,6 +90,13 @@ int git_config_add_file_ondisk( git_config_file *file = NULL; int res; + assert(cfg && path); + + if (!git_path_isfile(path)) { + giterr_set(GITERR_CONFIG, "File '%s' doesn't exists.", path); + return GIT_ENOTFOUND; + } + if (git_config_file__ondisk(&file, path) < 0) return -1; @@ -105,17 +112,22 @@ int git_config_add_file_ondisk( return 0; } -int git_config_open_ondisk(git_config **cfg, const char *path) +int git_config_open_ondisk(git_config **out, const char *path) { - if (git_config_new(cfg) < 0) - return -1; + int error; + git_config *config; - if (git_config_add_file_ondisk(*cfg, path, GIT_CONFIG_LEVEL_LOCAL, 0) < 0) { - git_config_free(*cfg); + *out = NULL; + + if (git_config_new(&config) < 0) return -1; - } - return 0; + if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0) + git_config_free(config); + else + *out = config; + + return error; } static int find_internal_file_by_level( diff --git a/src/repository.c b/src/repository.c index 2d6ce4dbb..c1756b1bc 100644 --- a/src/repository.c +++ b/src/repository.c @@ -750,6 +750,23 @@ static bool are_symlinks_supported(const char *wd_path) return _symlinks_supported; } +static int create_empty_file(const char *path, mode_t mode) +{ + int fd; + + if ((fd = p_creat(path, mode)) < 0) { + giterr_set(GITERR_OS, "Error while creating '%s'", path); + return -1; + } + + if (p_close(fd) < 0) { + giterr_set(GITERR_OS, "Error while closing '%s'", path); + return -1; + } + + return 0; +} + static int repo_init_config( const char *repo_dir, const char *work_dir, @@ -766,6 +783,12 @@ static int repo_init_config( if (git_buf_joinpath(&cfg_path, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0) return -1; + if (!git_path_isfile(git_buf_cstr(&cfg_path)) && + create_empty_file(git_buf_cstr(&cfg_path), GIT_CONFIG_FILE_MODE) < 0) { + git_buf_free(&cfg_path); + return -1; + } + if (git_config_open_ondisk(&config, git_buf_cstr(&cfg_path)) < 0) { git_buf_free(&cfg_path); return -1; diff --git a/tests-clar/config/new.c b/tests-clar/config/new.c index 6bd719fba..dd6dbca9e 100644 --- a/tests-clar/config/new.c +++ b/tests-clar/config/new.c @@ -11,6 +11,7 @@ void test_config_new__write_new_config(void) const char *out; git_config *config; + cl_git_mkfile(TEST_CONFIG, ""); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "color.ui", "auto")); diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c index 7b30b6e12..d63ef4c91 100644 --- a/tests-clar/config/read.c +++ b/tests-clar/config/read.c @@ -430,3 +430,23 @@ void test_config_read__simple_read_from_specific_level(void) git_config_free(cfg_specific); git_config_free(cfg); } + +void test_config_read__can_load_and_parse_an_empty_config_file(void) +{ + git_config *cfg; + int i; + + cl_git_mkfile("./empty", ""); + cl_git_pass(git_config_open_ondisk(&cfg, "./empty")); + cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither")); + + git_config_free(cfg); +} + +void test_config_read__cannot_load_a_non_existing_config_file(void) +{ + git_config *cfg; + int i; + + cl_assert_equal_i(GIT_ENOTFOUND, git_config_open_ondisk(&cfg, "./no.config")); +} |