diff options
Diffstat (limited to 'src/rebar_config.erl')
-rw-r--r-- | src/rebar_config.erl | 171 |
1 files changed, 114 insertions, 57 deletions
diff --git a/src/rebar_config.erl b/src/rebar_config.erl index 7f7d03c..461de5d 100644 --- a/src/rebar_config.erl +++ b/src/rebar_config.erl @@ -30,29 +30,36 @@ get/3, get_local/3, get_list/3, get_all/2, set/3, - set_global/2, get_global/2, - is_verbose/0, get_jobs/0, - set_env/3, get_env/2]). + set_global/3, get_global/3, + is_verbose/1, + save_env/3, get_env/2, reset_envs/1, + set_skip_dir/2, is_skip_dir/2, reset_skip_dirs/1, + clean_config/2, + set_xconf/3, get_xconf/2, get_xconf/3, erase_xconf/2]). -include("rebar.hrl"). -record(config, { dir :: file:filename(), opts = [] :: list(), - envs = new_env() :: dict() }). + globals = new_globals() :: dict(), + envs = new_env() :: dict(), + %% cross-directory/-command config + skip_dirs = new_skip_dirs() :: dict(), + xconf = new_xconf() :: dict() }). -%% Types that can be used from other modules -- alphabetically ordered. -export_type([config/0]). -%% data types -opaque config() :: #config{}. +-define(DEFAULT_NAME, "rebar.config"). + %% =================================================================== %% Public API %% =================================================================== -base_config(#config{opts=Opts0}) -> - ConfName = rebar_config:get_global(config, "rebar.config"), - new(Opts0, ConfName). +base_config(GlobalConfig) -> + ConfName = rebar_config:get_global(GlobalConfig, config, ?DEFAULT_NAME), + new(GlobalConfig, ConfName). new() -> #config{dir = rebar_utils:get_cwd()}. @@ -65,31 +72,10 @@ new(ConfigFile) when is_list(ConfigFile) -> Other -> ?ABORT("Failed to load ~s: ~p~n", [ConfigFile, Other]) end; -new(_ParentConfig=#config{opts=Opts0})-> - new(Opts0, "rebar.config"). - -new(Opts0, ConfName) -> - %% Load terms from rebar.config, if it exists - Dir = rebar_utils:get_cwd(), - ConfigFile = filename:join([Dir, ConfName]), - Opts = case consult_file(ConfigFile) of - {ok, Terms} -> - %% Found a config file with some terms. We need to - %% be able to distinguish between local definitions - %% (i.e. from the file in the cwd) and inherited - %% definitions. To accomplish this, we use a marker - %% in the proplist (since order matters) between - %% the new and old defs. - Terms ++ [local] ++ - [Opt || Opt <- Opts0, Opt /= local]; - {error, enoent} -> - [local] ++ - [Opt || Opt <- Opts0, Opt /= local]; - Other -> - ?ABORT("Failed to load ~s: ~p\n", [ConfigFile, Other]) - end, - - #config{dir = Dir, opts = Opts}. +new(_ParentConfig=#config{opts=Opts0, globals=Globals, skip_dirs=SkipDirs, + xconf=Xconf}) -> + new(#config{opts=Opts0, globals=Globals, skip_dirs=SkipDirs, xconf=Xconf}, + ?DEFAULT_NAME). get(Config, Key, Default) -> proplists:get_value(Key, Config#config.opts, Default). @@ -107,27 +93,26 @@ set(Config, Key, Value) -> Opts = proplists:delete(Key, Config#config.opts), Config#config { opts = [{Key, Value} | Opts] }. -set_global(jobs=Key, Value) when is_list(Value) -> - set_global(Key, list_to_integer(Value)); -set_global(jobs=Key, Value) when is_integer(Value) -> - application:set_env(rebar_global, Key, erlang:max(1, Value)); -set_global(Key, Value) -> - application:set_env(rebar_global, Key, Value). - -get_global(Key, Default) -> - case application:get_env(rebar_global, Key) of - undefined -> +set_global(Config, jobs=Key, Value) when is_list(Value) -> + set_global(Config, Key, list_to_integer(Value)); +set_global(Config, jobs=Key, Value) when is_integer(Value) -> + NewGlobals = dict:store(Key, erlang:max(1, Value), Config#config.globals), + Config#config{globals = NewGlobals}; +set_global(Config, Key, Value) -> + NewGlobals = dict:store(Key, Value, Config#config.globals), + Config#config{globals = NewGlobals}. + +get_global(Config, Key, Default) -> + case dict:find(Key, Config#config.globals) of + error -> Default; {ok, Value} -> Value end. -is_verbose() -> +is_verbose(Config) -> DefaulLevel = rebar_log:default_level(), - get_global(verbose, DefaulLevel) > DefaulLevel. - -get_jobs() -> - get_global(jobs, 3). + get_global(Config, verbose, DefaulLevel) > DefaulLevel. consult_file(File) -> case filename:extension(File) of @@ -144,24 +129,90 @@ consult_file(File) -> end end. -set_env(Config, Mod, Env) -> - OldEnvs = Config#config.envs, - NewEnvs = dict:store(Mod, Env, OldEnvs), - Config#config{envs=NewEnvs}. +save_env(Config, Mod, Env) -> + NewEnvs = dict:store(Mod, Env, Config#config.envs), + Config#config{envs = NewEnvs}. get_env(Config, Mod) -> dict:fetch(Mod, Config#config.envs). +reset_envs(Config) -> + Config#config{envs = new_env()}. + +set_skip_dir(Config, Dir) -> + OldSkipDirs = Config#config.skip_dirs, + NewSkipDirs = case is_skip_dir(Config, Dir) of + false -> + ?DEBUG("Adding skip dir: ~s\n", [Dir]), + dict:store(Dir, true, OldSkipDirs); + true -> + OldSkipDirs + end, + Config#config{skip_dirs = NewSkipDirs}. + +is_skip_dir(Config, Dir) -> + dict:is_key(Dir, Config#config.skip_dirs). + +reset_skip_dirs(Config) -> + Config#config{skip_dirs = new_skip_dirs()}. + +set_xconf(Config, Key, Value) -> + NewXconf = dict:store(Key, Value, Config#config.xconf), + Config#config{xconf=NewXconf}. + +get_xconf(Config, Key) -> + {ok, Value} = dict:find(Key, Config#config.xconf), + Value. + +get_xconf(Config, Key, Default) -> + case dict:find(Key, Config#config.xconf) of + error -> + Default; + {ok, Value} -> + Value + end. + +erase_xconf(Config, Key) -> + NewXconf = dict:erase(Key, Config#config.xconf), + Config#config{xconf = NewXconf}. + +%% TODO: reconsider after config inheritance removal/redesign +clean_config(Old, New) -> + New#config{opts=Old#config.opts}. + %% =================================================================== %% Internal functions %% =================================================================== +new(ParentConfig, ConfName) -> + %% Load terms from rebar.config, if it exists + Dir = rebar_utils:get_cwd(), + ConfigFile = filename:join([Dir, ConfName]), + Opts0 = ParentConfig#config.opts, + Opts = case consult_file(ConfigFile) of + {ok, Terms} -> + %% Found a config file with some terms. We need to + %% be able to distinguish between local definitions + %% (i.e. from the file in the cwd) and inherited + %% definitions. To accomplish this, we use a marker + %% in the proplist (since order matters) between + %% the new and old defs. + Terms ++ [local] ++ + [Opt || Opt <- Opts0, Opt /= local]; + {error, enoent} -> + [local] ++ + [Opt || Opt <- Opts0, Opt /= local]; + Other -> + ?ABORT("Failed to load ~s: ~p\n", [ConfigFile, Other]) + end, + + ParentConfig#config{dir = Dir, opts = Opts}. + consult_and_eval(File, Script) -> ?DEBUG("Evaluating config script ~p~n", [Script]), ConfigData = try_consult(File), file:script(Script, bs([{'CONFIG', ConfigData}, {'SCRIPT', Script}])). - remove_script_ext(F) -> "tpircs." ++ Rev = lists:reverse(F), lists:reverse(Rev). @@ -171,7 +222,8 @@ try_consult(File) -> {ok, Terms} -> ?DEBUG("Consult config file ~p~n", [File]), Terms; - {error, enoent} -> []; + {error, enoent} -> + []; {error, Reason} -> ?ABORT("Failed to read config file ~s: ~p~n", [File, Reason]) end. @@ -188,5 +240,10 @@ local_opts([local | _Rest], Acc) -> local_opts([Item | Rest], Acc) -> local_opts(Rest, [Item | Acc]). -new_env() -> - dict:new(). +new_globals() -> dict:new(). + +new_env() -> dict:new(). + +new_skip_dirs() -> dict:new(). + +new_xconf() -> dict:new(). |