summaryrefslogtreecommitdiff
path: root/src/rebar_config.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_config.erl')
-rw-r--r--src/rebar_config.erl171
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().