diff --git a/ext/rugged/rugged.h b/ext/rugged/rugged.h index 4ef0db1a3..87a656f1b 100644 --- a/ext/rugged/rugged.h +++ b/ext/rugged/rugged.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/ext/rugged/rugged_config.c b/ext/rugged/rugged_config.c index bf1f7cd78..f7cf90bef 100644 --- a/ext/rugged/rugged_config.c +++ b/ext/rugged/rugged_config.c @@ -384,6 +384,65 @@ static VALUE rb_git_config_transaction(VALUE self) return rb_result; } +/* + * call-seq: + * config.add_backend(backend, level, force = false) -> config + * + * Add a backend to be used by the config. + * + * A backend can only be assigned once, and becomes unusable from that + * point on. Trying to assign a backend a second time will raise an + * exception. + */ +static VALUE rb_git_config_add_backend(int argc, VALUE *argv, VALUE self) +{ + git_config *config; + git_config_backend *backend; + ID id_level; + git_config_level_t level; + VALUE rb_backend, rb_level, rb_force; + + rb_scan_args(argc, argv, "21", &rb_backend, &rb_level, &rb_force); + + // TODO: Check rb_backend + + Check_Type(rb_level, T_SYMBOL); + + id_level = SYM2ID(rb_level); + + if (id_level == rb_intern("system")) { + level = GIT_CONFIG_LEVEL_SYSTEM; + } else if (id_level == rb_intern("xdg")) { + level = GIT_CONFIG_LEVEL_XDG; + } else if (id_level == rb_intern("global")) { + level = GIT_CONFIG_LEVEL_GLOBAL; + } else if (id_level == rb_intern("local")) { + level = GIT_CONFIG_LEVEL_LOCAL; + } else if (id_level == rb_intern("app")) { + level = GIT_CONFIG_LEVEL_APP; + } else if (id_level == rb_intern("highest")) { + level = GIT_CONFIG_HIGHEST_LEVEL; + } else { + rb_raise(rb_eArgError, "Invalid config backend level."); + } + + // TODO: if (!NIL_P(rb_force) && rb_force != Qtrue && rb_force != Qfalse) + + Data_Get_Struct(self, git_config, config); + Data_Get_Struct(rb_backend, git_config_backend, backend); + + if (!backend) + rb_exc_raise(rb_exc_new2(rb_eRuntimeError, "Can not reuse config backend instances")); + + rugged_exception_check(git_config_add_backend(config, backend, level, RTEST(rb_force))); + + // libgit2 has taken ownership of the backend, so we should make sure + // we don't try to free it. + ((struct RData *)rb_backend)->data = NULL; + + return self; +} + void Init_rugged_config(void) { /* @@ -397,6 +456,8 @@ void Init_rugged_config(void) rb_define_method(rb_cRuggedConfig, "delete", rb_git_config_delete, 1); + rb_define_method(rb_cRuggedConfig, "add_backend", rb_git_config_add_backend, -1); + rb_define_method(rb_cRuggedConfig, "store", rb_git_config_store, 2); rb_define_method(rb_cRuggedConfig, "[]=", rb_git_config_store, 2);