diff --git a/c_src/config.c b/c_src/config.c index 974d669..1118e5a 100644 --- a/c_src/config.c +++ b/c_src/config.c @@ -8,6 +8,34 @@ void geef_config_free(ErlNifEnv *env, void *cd) git_config_free(cfg->config); } +ERL_NIF_TERM +geef_config_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_config *cfg; + ErlNifBinary bin; + ERL_NIF_TERM term_cfg; + int error; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &bin)) + return enif_make_badarg(env); + + if (!geef_terminate_binary(&bin)) + return geef_oom(env); + + cfg = enif_alloc_resource(geef_config_type, sizeof(geef_config)); + error = git_config_open_ondisk(&cfg->config, (char *) bin.data); + enif_release_binary(&bin); + + if (error < 0) + return geef_error(env); + + term_cfg = enif_make_resource(env, cfg); + enif_release_resource(cfg); + + return enif_make_tuple2(env, atoms.ok, term_cfg); + +} + static ERL_NIF_TERM extract(geef_config **cfg, ErlNifBinary *bin, ErlNifEnv *env, const ERL_NIF_TERM argv[]) { if (!enif_get_resource(env, argv[0], geef_config_type, (void **) cfg)) diff --git a/c_src/config.h b/c_src/config.h index c91a2a9..215f1da 100644 --- a/c_src/config.h +++ b/c_src/config.h @@ -7,6 +7,7 @@ void geef_config_free(ErlNifEnv *env, void *cd); ERL_NIF_TERM geef_config_set_bool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_config_get_bool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_config_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); extern ErlNifResourceType *geef_config_type; diff --git a/c_src/geef.c b/c_src/geef.c index dbd708b..3758d79 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -218,6 +218,7 @@ static ErlNifFunc geef_funcs[] = {"revparse_single", 2, geef_revparse_single}, {"config_set_bool", 3, geef_config_set_bool}, {"config_get_bool", 2, geef_config_get_bool}, + {"config_open", 1, geef_config_open}, }; ERL_NIF_INIT(geef_nif, geef_funcs, load, NULL, upgrade, unload) diff --git a/src/geef_config.erl b/src/geef_config.erl index 6b86e2e..8f3bb7f 100644 --- a/src/geef_config.erl +++ b/src/geef_config.erl @@ -36,6 +36,16 @@ start_link(Handle) -> gen_server:start_link(?MODULE, Handle, []). +%% @doc Open a configuration file +-spec open(iolist()) -> {ok, pid()} | {error, term()}. +open(Path) -> + case geef_nif:config_open(Path) of + {ok, Handle} -> + start_link(Handle); + Error -> + Error + end. + %% @doc Set a value in the configuration set(Pid, Name, Val) when is_boolean(Val) -> gen_server:call(Pid, {set_bool, Name, Val}). diff --git a/src/geef_nif.erl b/src/geef_nif.erl index bcbc7eb..ae15834 100644 --- a/src/geef_nif.erl +++ b/src/geef_nif.erl @@ -213,6 +213,10 @@ config_set_bool(_Handle, _Name, _Val) -> config_get_bool(_Handle, _Name) -> ?NIF_FN. +-spec config_open(iolist()) -> {ok, term()} | {error, term()}. +config_open(_Path) -> + ?NIF_FN. + nif_error(Line) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). diff --git a/test/config_test.erl b/test/config_test.erl new file mode 100644 index 0000000..21851c4 --- /dev/null +++ b/test/config_test.erl @@ -0,0 +1,22 @@ +-module(config_test). +-compile([export_all]). +-include_lib("eunit/include/eunit.hrl"). +-include("src/geef_records.hrl"). + +config_test() -> + {foreach, fun start/0, fun stop/1, [fun bool_test/1]}. + +start() -> + {A, B, C} = now(), + N = node(), + TmpFile = io_lib:format("/tmp/geef-~p~p~p~p.gitconfig", [N, A, B, C]), + {ok, Config} = geef_config:open(TmpFile), + {Config, TmpFile}. + +bool_test({Config, _}) -> + Var = "core.logallrefupdates", + ok = geef_config:set(Config, Var, true), + [?_assertEqual({ok, true}, geef_config:get_bool(Config, Var))]. + +stop({_, Path}) -> + ok = file:delete(Path).