From 629792f36baaaddaeb8ce654760ca4392a571cc5 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 17 Aug 2014 21:10:43 -0500 Subject: start of moving to splitting state from config parsing --- src/rebar.erl | 146 ++++++++++------------ src/rebar_app_discover.erl | 19 +-- src/rebar_app_utils.erl | 16 +-- src/rebar_base_compiler.erl | 2 +- src/rebar_config.erl | 271 ++-------------------------------------- src/rebar_core.erl | 53 ++------ src/rebar_deps.erl | 43 +++---- src/rebar_erlc_compiler.erl | 54 ++++---- src/rebar_erlydtl_compiler.erl | 6 +- src/rebar_escripter.erl | 24 ++-- src/rebar_lock.erl | 13 ++ src/rebar_log.erl | 3 +- src/rebar_otp_app.erl | 5 +- src/rebar_provider.erl | 14 +-- src/rebar_prv_app_builder.erl | 63 +++------- src/rebar_prv_app_discovery.erl | 36 ++++++ src/rebar_prv_release.erl | 8 +- src/rebar_prv_tar.erl | 8 +- src/rebar_prv_update.erl | 21 ++-- src/rebar_shell.erl | 6 +- src/rebar_state.erl | 159 +++++++++++++++++++++++ src/rebar_utils.erl | 40 +++--- 22 files changed, 443 insertions(+), 567 deletions(-) create mode 100644 src/rebar_lock.erl create mode 100644 src/rebar_prv_app_discovery.erl create mode 100644 src/rebar_state.erl (limited to 'src') diff --git a/src/rebar.erl b/src/rebar.erl index dd6d6d0..a7bbe1a 100644 --- a/src/rebar.erl +++ b/src/rebar.erl @@ -30,8 +30,7 @@ run/2, help/0, parse_args/1, - version/0, - get_jobs/1]). + version/0]). -include("rebar.hrl"). @@ -103,7 +102,7 @@ run(RawArgs) -> BaseConfig = init_config(Args), {BaseConfig1, Cmds} = save_options(BaseConfig, Args), - case rebar_config:get_xconf(BaseConfig1, enable_profiling, false) of + case rebar_state:get(BaseConfig1, enable_profiling, false) of true -> io:format("Profiling!\n"), try @@ -121,43 +120,41 @@ load_rebar_app() -> ok = application:load(rebar). init_config({Options, _NonOptArgs}) -> - %% If $HOME/.rebar/config exists load and use as global config - GlobalConfigFile = filename:join([os:getenv("HOME"), ".rebar", "config"]), - GlobalConfig = case filelib:is_regular(GlobalConfigFile) of - true -> - ?DEBUG("Load global config file ~p~n", - [GlobalConfigFile]), - rebar_config:new(GlobalConfigFile); - false -> - rebar_config:new() - end, - - %% Set the rebar config to use - GlobalConfig1 = case proplists:get_value(config, Options) of - undefined -> - GlobalConfig; - Conf -> - rebar_config:set_global(GlobalConfig, config, Conf) - end, - - GlobalConfig2 = set_log_level(GlobalConfig1, Options), %% Initialize logging system - ok = rebar_log:init(command_line, GlobalConfig2), + Verbosity = log_level(Options), + ok = rebar_log:init(command_line, Verbosity), - BaseConfig = rebar_config:base_config(GlobalConfig2), + Config = case proplists:get_value(config, Options) of + undefined -> + rebar_config:consult_file(?DEFAULT_CONFIG_FILE); + ConfigFile -> + rebar_config:consult_file(ConfigFile) + end, + + %% If $HOME/.rebar/config exists load and use as global config + GlobalConfigFile = filename:join([os:getenv("HOME"), ".rebar", "config"]), + State = case filelib:is_regular(GlobalConfigFile) of + true -> + ?DEBUG("Load global config file ~p~n", + [GlobalConfigFile]), + rebar_config:consult_file(GlobalConfigFile), + rebar_state:new(GlobalConfigFile, Config); + false -> + rebar_state:new(Config) + end, %% Initialize vsn cache - rebar_config:set_xconf(BaseConfig, vsn_cache, dict:new()). + rebar_state:set(State, vsn_cache, dict:new()). init_config1(BaseConfig) -> %% Determine the location of the rebar executable; important for pulling %% resources out of the escript ScriptName = filename:absname(escript:script_name()), - BaseConfig1 = rebar_config:set_xconf(BaseConfig, escript, ScriptName), + BaseConfig1 = rebar_state:set(BaseConfig, escript, ScriptName), ?DEBUG("Rebar location: ~p\n", [ScriptName]), %% Note the top-level directory for reference AbsCwd = filename:absname(rebar_utils:get_cwd()), - rebar_config:set_xconf(BaseConfig1, base_dir, AbsCwd). + rebar_state:set(BaseConfig1, base_dir, AbsCwd). run_aux(BaseConfig, Commands) -> %% Make sure crypto is running @@ -173,8 +170,8 @@ run_aux(BaseConfig, Commands) -> %% Process each command, resetting any state between each one {ok, Providers} = application:get_env(rebar, providers), - BaseConfig2 = rebar_config:create_logic_providers(Providers, BaseConfig1), - rebar_core:process_commands(CommandAtom, rebar_config:command_args(BaseConfig2, Args)), + BaseConfig2 = rebar_state:create_logic_providers(Providers, BaseConfig1), + rebar_core:process_command(rebar_state:command_args(BaseConfig2, Args), CommandAtom), ok. %% @@ -208,64 +205,47 @@ parse_args(RawArgs) -> rebar_utils:delayed_halt(1) end. -save_options(Config, {Options, NonOptArgs}) -> +save_options(State, {Options, NonOptArgs}) -> %% Check options and maybe halt execution ok = show_info_maybe_halt(Options, NonOptArgs), GlobalDefines = proplists:get_all_values(defines, Options), - Config1 = rebar_config:set_xconf(Config, defines, GlobalDefines), + State1 = rebar_state:set(State, defines, GlobalDefines), %% Setup profiling flag - Config2 = rebar_config:set_xconf(Config1, enable_profiling, - proplists:get_bool(profile, Options)), - - %% Setup flag to keep running after a single command fails - Config3 = rebar_config:set_xconf(Config2, keep_going, - proplists:get_bool(keep_going, Options)), - - %% Setup flag to enable recursive application of commands - Config4 = rebar_config:set_xconf(Config3, recursive, - proplists:get_bool(recursive, Options)), + State2 = rebar_state:set(State1, enable_profiling, + proplists:get_bool(profile, Options)), %% Set global variables based on getopt options - Config5 = set_global_flag(Config4, Options, force), - Config6 = case proplists:get_value(jobs, Options, ?DEFAULT_JOBS) of + State3 = set_global_flag(State2, Options, force), + State4 = case proplists:get_value(jobs, Options, ?DEFAULT_JOBS) of ?DEFAULT_JOBS -> - Config5; + State3; Jobs -> - rebar_config:set_global(Config5, jobs, Jobs) + rebar_state:set(State3, jobs, Jobs) end, %% Filter all the flags (i.e. strings of form key=value) from the %% command line arguments. What's left will be the commands to run. - {Config7, RawCmds} = filter_flags(Config6, NonOptArgs, []), - {Config7, RawCmds}. + {State5, RawCmds} = filter_flags(State4, NonOptArgs, []), + {State5, RawCmds}. %% -%% set log level based on getopt option +%% get log level based on getopt option %% -set_log_level(Config, Options) -> - {IsVerbose, Level} = - case proplists:get_bool(quiet, Options) of - true -> - {false, rebar_log:error_level()}; - false -> - DefaultLevel = rebar_log:default_level(), - case proplists:get_all_values(verbose, Options) of - [] -> - {false, DefaultLevel}; - Verbosities -> - {true, DefaultLevel + lists:last(Verbosities)} - end - end, - - case IsVerbose of +log_level(Options) -> + case proplists:get_bool(quiet, Options) of true -> - Config1 = rebar_config:set_xconf(Config, is_verbose, true), - rebar_config:set_global(Config1, verbose, Level); + rebar_log:error_level(); false -> - rebar_config:set_global(Config, verbose, Level) + DefaultLevel = rebar_log:default_level(), + case proplists:get_all_values(verbose, Options) of + [] -> + DefaultLevel; + Verbosities -> + DefaultLevel + lists:last(Verbosities) + end end. %% @@ -280,14 +260,14 @@ version() -> %% %% set global flag based on getopt option boolean value %% -set_global_flag(Config, Options, Flag) -> +set_global_flag(State, Options, Flag) -> Value = case proplists:get_bool(Flag, Options) of true -> "1"; false -> "0" end, - rebar_config:set_global(Config, Flag, Value). + rebar_state:set(State, Flag, Value). %% %% show info and maybe halt execution @@ -322,6 +302,8 @@ commands() -> clean Clean compile Compile sources +do + escriptize Generate escript archive shell Start a shell similar to @@ -329,14 +311,16 @@ shell Start a shell similar to update [dep] Update source dep +ct +eunit + +new + help Show the program options version Show version information ">>, io:put_chars(S). -get_jobs(Config) -> - rebar_config:get_global(Config, jobs, ?DEFAULT_JOBS). - %% %% options accepted via getopt %% @@ -365,14 +349,14 @@ option_spec_list() -> %% %% Seperate all commands (single-words) from flags (key=value) and store -%% values into the rebar_config global storage. +%% values into the rebar_state global storage. %% -filter_flags(Config, [], Commands) -> - {Config, lists:reverse(Commands)}; -filter_flags(Config, [Item | Rest], Commands) -> +filter_flags(State, [], Commands) -> + {State, lists:reverse(Commands)}; +filter_flags(State, [Item | Rest], Commands) -> case string:tokens(Item, "=") of [Command] -> - filter_flags(Config, Rest, [Command | Commands]); + filter_flags(State, Rest, [Command | Commands]); [KeyStr, RawValue] -> Key = list_to_atom(KeyStr), Value = case Key of @@ -381,11 +365,11 @@ filter_flags(Config, [Item | Rest], Commands) -> _ -> RawValue end, - Config1 = rebar_config:set_global(Config, Key, Value), - filter_flags(Config1, Rest, Commands); + State1 = rebar_state:set(State, Key, Value), + filter_flags(State1, Rest, Commands); Other -> ?CONSOLE("Ignoring command line argument: ~p\n", [Other]), - filter_flags(Config, Rest, Commands) + filter_flags(State, Rest, Commands) end. command_names() -> diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 4252262..9e9a108 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -3,11 +3,11 @@ -export([do/2, find_apps/1]). -do(Config, LibDirs) -> +do(State, LibDirs) -> Apps = find_apps(LibDirs), - lists:foldl(fun(AppInfo, ConfigAcc) -> - rebar_config:add_app(ConfigAcc, AppInfo) - end, Config, Apps). + lists:foldl(fun(AppInfo, StateAcc) -> + rebar_state:add_app(StateAcc, AppInfo) + end, State, Apps). -spec all_app_dirs(list(file:name())) -> list(file:name()). all_app_dirs(LibDirs) -> @@ -72,13 +72,14 @@ create_app_info(AppDir, AppFile) -> AbsCwd = filename:absname(rebar_utils:get_cwd()), {ok, AppInfo} = rebar_app_info:new(AppName, AppVsn, AppDir), RebarConfig = filename:join(AppDir, "rebar.config"), - AppConfig = case filelib:is_file(RebarConfig) of + AppState = case filelib:is_file(RebarConfig) of true -> - rebar_config:new(RebarConfig); + Terms = rebar_config:consult_file(RebarConfig), + rebar_state:new(Terms); false -> - rebar_config:new() + rebar_state:new() end, - AppConfig1 = rebar_config:set_xconf(AppConfig, base_dir, AbsCwd), - AppInfo1 = rebar_app_info:config(AppInfo, AppConfig1), + AppState1 = rebar_state:set(AppState, base_dir, AbsCwd), + AppInfo1 = rebar_app_info:config(AppInfo, AppState1), rebar_app_info:dir(AppInfo1, AppDir) end. diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index bbcbaf4..8544329 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -137,23 +137,23 @@ is_skipped_app(Config, AppFile) -> %% Internal functions %% =================================================================== -load_app_file(Config, Filename) -> +load_app_file(State, Filename) -> AppFile = {app_file, Filename}, - case rebar_config:get_xconf(Config, {appfile, AppFile}, undefined) of + case rebar_state:get(State, {appfile, AppFile}, undefined) of undefined -> case consult_app_file(Filename) of {ok, [{application, AppName, AppData}]} -> - Config1 = rebar_config:set_xconf(Config, - {appfile, AppFile}, - {AppName, AppData}), - {ok, Config1, AppName, AppData}; + State1 = rebar_state:set(State, + {appfile, AppFile}, + {AppName, AppData}), + {ok, State1, AppName, AppData}; {error, _} = Error -> Error; Other -> {error, {unexpected_terms, Other}} end; {AppName, AppData} -> - {ok, Config, AppName, AppData} + {ok, State, AppName, AppData} end. %% In the case of *.app.src we want to give the user the ability to @@ -166,7 +166,7 @@ consult_app_file(Filename) -> false -> file:consult(Filename); true -> - rebar_config:consult_file(Filename) + {ok, rebar_config:consult_file(Filename)} end. get_value(Key, AppInfo, AppFile) -> diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index 278c159..bf08ee6 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -49,7 +49,7 @@ run(Config, FirstFiles, RestFiles, CompileFn) -> _ -> Self = self(), F = fun() -> compile_worker(Self, Config, CompileFn) end, - Jobs = rebar:get_jobs(Config), + Jobs = rebar_state:get(Config, jobs, 3), ?DEBUG("Starting ~B compile worker(s)~n", [Jobs]), Pids = [spawn_monitor(F) || _I <- lists:seq(1,Jobs)], compile_queue(Config, Pids, RestFiles) diff --git a/src/rebar_config.erl b/src/rebar_config.erl index 50682e0..a45bef9 100644 --- a/src/rebar_config.erl +++ b/src/rebar_config.erl @@ -26,148 +26,20 @@ %% ------------------------------------------------------------------- -module(rebar_config). --export([new/0, new/1, new/2, new2/2, base_config/1, consult_file/1, - get/3, get_local/3, get_list/3, - get_all/2, - set/3, - command_args/1, command_args/2, - set_global/3, get_global/3, - is_recursive/1, - save_env/3, get_env/2, reset_envs/1, - set_skip_dir/2, is_skip_dir/2, reset_skip_dirs/1, - create_logic_providers/2, - providers/1, providers/2, add_provider/2, - add_dep/2, get_dep/2, deps/2, deps/1, deps_graph/1, deps_graph/2, deps_to_build/1, - goals/1, goals/2, - get_app/2, apps_to_build/1, apps_to_build/2, add_app/2, replace_app/3, - set_xconf/3, get_xconf/2, get_xconf/3, erase_xconf/2]). +-export([consult/1 + ,consult_file/1]). -include("rebar.hrl"). --ifdef(namespaced_types). -%% dict:dict() exists starting from Erlang 17. --type rebar_dict() :: dict:dict(term(), term()). --else. -%% dict() has been obsoleted in Erlang 17 and deprecated in 18. --type rebar_dict() :: dict(). --endif. - --record(config, { dir :: file:filename(), - opts = [] :: list(), - local_opts = [] :: list(), - globals = new_globals() :: rebar_dict(), - envs = new_env() :: rebar_dict(), - command_args = [] :: list(), - %% cross-directory/-command config - goals = [], - providers = [], - apps_to_build = [], - deps_to_build = [], - deps = [], - deps_graph = undefined, - skip_dirs = new_skip_dirs() :: rebar_dict(), - xconf = new_xconf() :: rebar_dict() }). - --export_type([config/0]). - --opaque config() :: #config{}. - --define(DEFAULT_NAME, "rebar.config"). --define(LOCK_FILE, "rebar.lock"). - %% =================================================================== %% Public API %% =================================================================== -base_config(GlobalConfig) -> - ConfName = rebar_config:get_global(GlobalConfig, config, ?DEFAULT_NAME), - new(GlobalConfig, ConfName). - -new() -> - #config{dir = rebar_utils:get_cwd()}. - -new(ConfigFile) when is_list(ConfigFile) -> - case consult_file(ConfigFile) of - {ok, Opts} -> - #config { dir = rebar_utils:get_cwd(), - opts = Opts }; - Other -> - ?ABORT("Failed to load ~s: ~p~n", [ConfigFile, Other]) - end; -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). - -new(ParentConfig=#config{}, ConfName) -> - %% Load terms from rebar.config, if it exists - Dir = rebar_utils:get_cwd(), - new(ParentConfig, ConfName, Dir). - -new2(_ParentConfig=#config{opts=Opts0, globals=Globals, skip_dirs=SkipDirs, xconf=Xconf}, Dir) -> - new(#config{opts=Opts0, globals=Globals, skip_dirs=SkipDirs, xconf=Xconf}, - ?DEFAULT_NAME, Dir). - -new(ParentConfig, ConfName, Dir) -> - ConfigFile = filename:join([Dir, ConfName]), - Opts0 = ParentConfig#config.opts, - Opts = case consult_file(ConfigFile) of - {ok, Terms} -> - Terms; - {error, enoent} -> - []; - Other -> - ?ABORT("Failed to load ~s: ~p\n", [ConfigFile, Other]) - end, - - Opts1 = case consult_file(?LOCK_FILE) of - {ok, [D]} -> - [{lock_deps, D} | Opts]; - _ -> - Opts - end, - - ProviderModules = [], - create_logic_providers(ProviderModules, ParentConfig#config{dir=Dir - ,local_opts=Opts1 - ,opts=Opts0}). - - -get(Config, Key, Default) -> - proplists:get_value(Key, Config#config.opts, Default). - -get_list(Config, Key, Default) -> - get(Config, Key, Default). - -get_local(Config, Key, Default) -> - proplists:get_value(Key, Config#config.local_opts, Default). - -get_all(Config, Key) -> - proplists:get_all_values(Key, Config#config.opts). - -set(Config, Key, Value) -> - Opts = proplists:delete(Key, Config#config.opts), - Config#config { opts = [{Key, Value} | Opts] }. - -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_recursive(Config) -> - get_xconf(Config, recursive, false). +-spec consult(file:name()) -> {ok, any()}. +consult(Dir) -> + consult_file(filename:join(Dir, ?DEFAULT_CONFIG_FILE)). +-spec consult_file(file:name()) -> {ok, any()}. consult_file(File) when is_binary(File) -> consult_file(binary_to_list(File)); consult_file(File) -> @@ -178,136 +50,25 @@ consult_file(File) -> Script = File ++ ".script", case filelib:is_regular(Script) of true -> - consult_and_eval(File, Script); + {ok, Terms} = consult_and_eval(File, Script), + Terms; false -> ?DEBUG("Consult config file ~p~n", [File]), - file:consult(File) + try_consult(File) end end. -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}. - -command_args(#config{command_args=CmdArgs}) -> - CmdArgs. - -command_args(Config, CmdArgs) -> - Config#config{command_args=CmdArgs}. - -get_dep(#config{deps=Apps}, Name) -> - lists:keyfind(Name, 2, Apps). - -deps(#config{deps=Apps}) -> - Apps. - -deps(Config, Apps) -> - Config#config{deps=Apps}. - -deps_graph(#config{deps_graph=Graph}) -> - Graph. - -deps_graph(Config, Graph) -> - Config#config{deps_graph=Graph}. - -get_app(#config{apps_to_build=Apps}, Name) -> - lists:keyfind(Name, 2, Apps). - -apps_to_build(#config{apps_to_build=Apps}) -> - Apps. - -apps_to_build(Config, Apps) -> - Config#config{apps_to_build=Apps}. - -add_app(Config=#config{apps_to_build=Apps}, App) -> - Config#config{apps_to_build=[App | Apps]}. - -replace_app(Config=#config{apps_to_build=Apps}, Name, App) -> - Apps1 = lists:keydelete(Name, 2, Apps), - Config#config{apps_to_build=[App | Apps1]}. - -deps_to_build(#config{deps_to_build=Apps}) -> - Apps. - -add_dep(Config=#config{deps_to_build=Apps}, App) -> - Config#config{deps_to_build=[App | Apps]}. - -providers(#config{providers=Providers}) -> - Providers. - -providers(Config, NewProviders) -> - Config#config{providers=NewProviders}. - -goals(#config{goals=Goals}) -> - Goals. - -goals(Config, Goals) -> - Config#config{goals=Goals}. - -add_provider(Config=#config{providers=Providers}, Provider) -> - Config#config{providers=[Provider | Providers]}. - -create_logic_providers(ProviderModules, State0) -> - lists:foldl(fun(ProviderMod, Acc) -> - {ok, State1} = rebar_provider:new(ProviderMod, Acc), - State1 - end, State0, ProviderModules). - %% =================================================================== %% Internal functions %% =================================================================== consult_and_eval(File, Script) -> ?DEBUG("Evaluating config script ~p~n", [Script]), - ConfigData = try_consult(File), - file:script(Script, bs([{'CONFIG', ConfigData}, {'SCRIPT', Script}])). + StateData = try_consult(File), + file:script(Script, bs([{'CONFIG', StateData}, {'SCRIPT', Script}])). remove_script_ext(F) -> - "tpircs." ++ Rev = lists:reverse(F), - lists:reverse(Rev). + filename:rootname(F, ".script"). try_consult(File) -> case file:consult(File) of @@ -324,11 +85,3 @@ bs(Vars) -> lists:foldl(fun({K,V}, Bs) -> erl_eval:add_binding(K, V, Bs) end, erl_eval:new_bindings(), Vars). - -new_globals() -> dict:new(). - -new_env() -> dict:new(). - -new_skip_dirs() -> dict:new(). - -new_xconf() -> dict:new(). diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 5dbdefb..f366b84 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -26,7 +26,7 @@ %% ------------------------------------------------------------------- -module(rebar_core). --export([process_commands/2, help/2]). +-export([process_command/2]). -include("rebar.hrl"). @@ -34,39 +34,20 @@ %% Internal functions %% =================================================================== -help(ParentConfig, Commands) -> - {ok, AllProviders} = application:get_env(rebar, providers), - - %% get plugin providers - Dir = rebar_utils:get_cwd(), - _Config = maybe_load_local_config(Dir, ParentConfig), - - lists:foreach( - fun(Cmd) -> - ?CONSOLE("==> help ~p~n~n", [Cmd]), - CmdProviders = rebar_provider:get_target_provider(Cmd, AllProviders), - Providers = rebar_provider:get_target_provider(info, CmdProviders), - lists:foreach(fun(M) -> - ?CONSOLE("=== ~p:~p ===~n", [M, Cmd]), - M:info(help, Cmd), - ?CONSOLE("~n", []) - end, Providers) - end, Commands). - -process_commands(Command, ParentConfig) -> +process_command(State, Command) -> true = rebar_utils:expand_code_path(), - LibDirs = rebar_config:get_local(ParentConfig, lib_dirs, ["apps", "libs", "."]), - DepsDir = rebar_deps:get_deps_dir(ParentConfig), + LibDirs = rebar_state:get(State, lib_dirs, ?DEFAULT_LIB_DIRS), + DepsDir = rebar_state:get(State, deps_dir, "deps"), _UpdatedCodePaths = update_code_path([DepsDir | LibDirs]), + rebar_deps:setup_env(State), + State2 = rebar_app_discover:do(State, LibDirs), + TargetProviders = rebar_provider:get_target_providers(Command, State2), - ParentConfig2 = rebar_app_discover:do(ParentConfig, LibDirs), - TargetProviders = rebar_provider:get_target_providers(Command, ParentConfig2), - ParentConfig3 = - lists:foldl(fun(TargetProvider, Conf) -> - Provider = rebar_provider:get_provider(TargetProvider, rebar_config:providers(Conf)), - {ok, Conf1} = rebar_provider:do(Provider, Conf), - Conf1 - end, ParentConfig2, TargetProviders). + lists:foldl(fun(TargetProvider, Conf) -> + Provider = rebar_provider:get_provider(TargetProvider, rebar_state:providers(Conf)), + {ok, Conf1} = rebar_provider:do(Provider, Conf), + Conf1 + end, State2, TargetProviders). update_code_path([]) -> no_change; @@ -86,13 +67,3 @@ expand_lib_dirs([Dir | Rest], Root, Acc) -> _ -> [filename:join([Root, A]) || A <- Apps] end, expand_lib_dirs(Rest, Root, Acc ++ FqApps). - -maybe_load_local_config(Dir, ParentConfig) -> - %% We need to ensure we don't overwrite custom - %% config when we are dealing with base_dir. - case rebar_utils:processing_base_dir(ParentConfig, Dir) of - true -> - ParentConfig; - false -> - rebar_config:new(ParentConfig) - end. diff --git a/src/rebar_deps.erl b/src/rebar_deps.erl index 69dce46..e52ed91 100644 --- a/src/rebar_deps.erl +++ b/src/rebar_deps.erl @@ -41,27 +41,27 @@ -export([get_deps_dir/2]). -define(PROVIDER, deps). --define(DEPS, []). +-define(DEPS, [app_discovery]). %% =================================================================== %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, - provider_impl = ?MODULE, - bare = false, - deps = ?DEPS, - example = "rebar deps", - short_desc = "", - desc = "", - opts = []}), + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, + provider_impl = ?MODULE, + bare = false, + deps = ?DEPS, + example = "rebar deps", + short_desc = "", + desc = "", + opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()}. do(Config) -> - Deps = rebar_config:get_local(Config, deps, []), + Deps = rebar_state:get(Config, deps, []), Goals = lists:map(fun({Name, "", _}) -> Name; ({Name, ".*", _}) -> @@ -71,9 +71,9 @@ do(Config) -> end, Deps), {Config1, Deps1} = update_deps(Config, Deps), - Config2 = rebar_config:deps(Config1, Deps1), + Config2 = rebar_state:set(Config1, deps, Deps1), - {ok, rebar_config:goals(Config2, Goals)}. + {ok, rebar_state:set(Config2, goals, Goals)}. update_deps(Config, Deps) -> DepsDir = get_deps_dir(Config), @@ -94,8 +94,9 @@ update_deps(Config, Deps) -> handle_deps(Deps, Found) -> NewDeps = lists:foldl(fun(X, DepsAcc) -> - C = rebar_config:new2(rebar_config:new(), rebar_app_info:dir(X)), - LocalDeps = rebar_config:get_local(C, deps, []), + C = rebar_config:consult(rebar_app_info:dir(X)), + S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(X)), + LocalDeps = rebar_state:get(S, deps, []), [LocalDeps | DepsAcc] end, [], Found), NewDeps1 = lists:flatten(NewDeps), @@ -106,7 +107,7 @@ handle_deps(Deps, Found) -> end, lists:usort(Deps), lists:usort(NewDeps1)). download_missing_deps(Config, DepsDir, Found, Deps) -> - Apps = rebar_config:apps_to_build(Config), + Apps = rebar_state:apps_to_build(Config), Missing = lists:filter(fun(X) -> not lists:any(fun(F) -> element(1, X) =:= element(2, F) @@ -125,14 +126,14 @@ download_missing_deps(Config, DepsDir, Found, Deps) -> Config1 = lists:foldl(fun(X, ConfigAcc) -> TargetDir = get_deps_dir(DepsDir, element(1, X)), [AppSrc] = rebar_app_discover:find_apps([TargetDir]), - rebar_config:add_dep(ConfigAcc, AppSrc) + rebar_state:add_app(ConfigAcc, AppSrc) end, Config, Missing), {Config1, Missing}. %% set REBAR_DEPS_DIR and ERL_LIBS environment variables setup_env(Config) -> - {true, DepsDir} = get_deps_dir(Config), + DepsDir = get_deps_dir(Config), %% include rebar's DepsDir in ERL_LIBS Separator = case os:type() of {win32, nt} -> @@ -149,8 +150,8 @@ setup_env(Config) -> [{"REBAR_DEPS_DIR", DepsDir}, ERL_LIBS]. -get_deps_dir(Config) -> - BaseDir = rebar_utils:base_dir(Config), +get_deps_dir(State) -> + BaseDir = rebar_state:get(State, base_dir, ""), get_deps_dir(BaseDir, "deps"). get_deps_dir(DepsDir, App) -> diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index ca670ac..9bebefb 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -91,26 +91,26 @@ %% 'old_inets'}]}. %% --spec compile(rebar_config:config(), file:name()) -> 'ok'. +-spec compile(rebar_state:t(), file:name()) -> 'ok'. compile(Config, Dir) -> rebar_base_compiler:run(Config, - check_files(rebar_config:get_local( + check_files(rebar_state:get( Config, xrl_first_files, [])), "src", ".xrl", "src", ".erl", fun compile_xrl/3), rebar_base_compiler:run(Config, - check_files(rebar_config:get_local( + check_files(rebar_state:get( Config, yrl_first_files, [])), "src", ".yrl", "src", ".erl", fun compile_yrl/3), rebar_base_compiler:run(Config, - check_files(rebar_config:get_local( + check_files(rebar_state:get( Config, mib_first_files, [])), "mibs", ".mib", "priv/mibs", ".bin", fun compile_mib/3), doterl_compile(Config, Dir). --spec clean(rebar_config:config(), file:filename()) -> 'ok'. +-spec clean(rebar_state:t(), file:filename()) -> 'ok'. clean(Config, _AppFile) -> MibFiles = rebar_utils:find_files("mibs", ?RE_PREFIX".*\\.mib\$"), MIBs = [filename:rootname(filename:basename(MIB)) || MIB <- MibFiles], @@ -234,22 +234,22 @@ test_compile_config_and_opts(Config, ErlOpts, Cmd) -> {Config3, EqcOpts} = eqc_opts(Config2), %% NOTE: For consistency, all *_first_files lists should be - %% retrieved via rebar_config:get_local. Right now + %% retrieved via rebar_state:get. Right now %% erl_first_files, eunit_first_files, and qc_first_files use - %% rebar_config:get_list and are inherited, but xrl_first_files - %% and yrl_first_files use rebar_config:get_local. Inheritance of + %% rebar_state:get_list and are inherited, but xrl_first_files + %% and yrl_first_files use rebar_state:get. Inheritance of %% *_first_files is questionable as the file would need to exist %% in all project directories for it to work. OptsAtom = list_to_atom(Cmd ++ "_compile_opts"), - TestOpts = rebar_config:get_list(Config3, OptsAtom, []), + TestOpts = rebar_state:get_list(Config3, OptsAtom, []), Opts0 = [{d, 'TEST'}] ++ ErlOpts ++ TestOpts ++ TriqOpts ++ PropErOpts ++ EqcOpts, Opts = [O || O <- Opts0, O =/= no_debug_info], - Config4 = rebar_config:set(Config3, erl_opts, Opts), + Config4 = rebar_state:set(Config3, erl_opts, Opts), FirstFilesAtom = list_to_atom(Cmd ++ "_first_files"), - FirstErls = rebar_config:get_list(Config4, FirstFilesAtom, []), - Config5 = rebar_config:set(Config4, erl_first_files, FirstErls), + FirstErls = rebar_state:get_list(Config4, FirstFilesAtom, []), + Config5 = rebar_state:set(Config4, erl_first_files, FirstErls), {Config5, Opts}. triq_opts(Config) -> @@ -274,7 +274,7 @@ define_if(Def, true) -> [{d, Def}]; define_if(_Def, false) -> []. is_lib_avail(Config, DictKey, Mod, Hrl, Name) -> - case rebar_config:get_xconf(Config, DictKey, undefined) of + case rebar_state:get_xconf(Config, DictKey, undefined) of undefined -> IsAvail = case code:lib_dir(Mod, include) of {error, bad_name} -> @@ -282,21 +282,21 @@ is_lib_avail(Config, DictKey, Mod, Hrl, Name) -> Dir -> filelib:is_regular(filename:join(Dir, Hrl)) end, - NewConfig = rebar_config:set_xconf(Config, DictKey, IsAvail), + NewConfig = rebar_state:set_xconf(Config, DictKey, IsAvail), ?DEBUG("~s availability: ~p\n", [Name, IsAvail]), {NewConfig, IsAvail}; IsAvail -> {Config, IsAvail} end. --spec doterl_compile(rebar_config:config(), file:filename()) -> 'ok'. +-spec doterl_compile(rebar_state:t(), file:filename()) -> 'ok'. doterl_compile(Config, Dir) -> ErlOpts = rebar_utils:erl_opts(Config), doterl_compile(Config, Dir, [], ErlOpts). doterl_compile(Config, Dir, MoreSources, ErlOpts) -> OutDir = filename:join(Dir, "ebin"), - ErlFirstFilesConf = rebar_config:get_list(Config, erl_first_modules, []), + ErlFirstFilesConf = rebar_state:get(Config, erl_first_modules, []), ?DEBUG("erl_opts ~p~n", [ErlOpts]), %% Support the src_dirs option allowing multiple directories to %% contain erlang source. This might be used, for example, should @@ -306,7 +306,7 @@ doterl_compile(Config, Dir, MoreSources, ErlOpts) -> end, rebar_utils:src_dirs(proplists:append_values(src_dirs, ErlOpts))), AllErlFiles = gather_src(SrcDirs, []) ++ MoreSources, %% NOTE: If and when erl_first_files is not inherited anymore - %% (rebar_config:get_local instead of rebar_config:get_list), consider + %% (rebar_state:get instead of rebar_state:get_list), consider %% logging a warning message for any file listed in erl_first_files which %% wasn't found via gather_src. {ErlFirstFiles, RestErls} = @@ -394,9 +394,9 @@ u_add_element(Elem, [E1|Set]) -> [E1|u_add_element(Elem, Set)]; u_add_element(Elem, []) -> [Elem]. -spec include_path(file:filename(), - rebar_config:config()) -> [file:filename(), ...]. + rebar_state:t()) -> [file:filename(), ...]. include_path(Source, Config) -> - ErlOpts = rebar_config:get(Config, erl_opts, []), + ErlOpts = rebar_state:get(Config, erl_opts, []), Dir = filename:join(lists:droplast(filename:split(filename:dirname(Source)))), lists:usort([filename:join(Dir, "include"), filename:dirname(Source)] ++ proplists:get_all_values(i, ErlOpts)). @@ -562,7 +562,7 @@ get_children(G, Source) -> %% Return all files dependent on the Source. digraph_utils:reaching_neighbours([Source], G). --spec internal_erl_compile(rebar_config:config(), file:filename(), file:filename(), +-spec internal_erl_compile(rebar_state:t(), file:filename(), file:filename(), file:filename(), list(), rebar_digraph()) -> 'ok' | 'skipped'. internal_erl_compile(Config, Dir, Source, OutDir, ErlOpts, G) -> @@ -595,12 +595,12 @@ internal_erl_compile(Config, Dir, Source, OutDir, ErlOpts, G) -> end. -spec compile_mib(file:filename(), file:filename(), - rebar_config:config()) -> 'ok'. + rebar_state:t()) -> 'ok'. compile_mib(Source, Target, Config) -> ok = rebar_utils:ensure_dir(Target), ok = rebar_utils:ensure_dir(filename:join("include", "dummy.hrl")), Opts = [{outdir, "priv/mibs"}, {i, ["priv/mibs"]}] ++ - rebar_config:get(Config, mib_opts, []), + rebar_state:get(Config, mib_opts, []), case snmpc:compile(Source, Opts) of {ok, _} -> Mib = filename:rootname(Target), @@ -620,18 +620,18 @@ compile_mib(Source, Target, Config) -> end. -spec compile_xrl(file:filename(), file:filename(), - rebar_config:config()) -> 'ok'. + rebar_state:t()) -> 'ok'. compile_xrl(Source, Target, Config) -> - Opts = [{scannerfile, Target} | rebar_config:get(Config, xrl_opts, [])], + Opts = [{scannerfile, Target} | rebar_state:get(Config, xrl_opts, [])], compile_xrl_yrl(Config, Source, Target, Opts, leex). -spec compile_yrl(file:filename(), file:filename(), - rebar_config:config()) -> 'ok'. + rebar_state:t()) -> 'ok'. compile_yrl(Source, Target, Config) -> - Opts = [{parserfile, Target} | rebar_config:get(Config, yrl_opts, [])], + Opts = [{parserfile, Target} | rebar_state:get(Config, yrl_opts, [])], compile_xrl_yrl(Config, Source, Target, Opts, yecc). --spec compile_xrl_yrl(rebar_config:config(), file:filename(), +-spec compile_xrl_yrl(rebar_state:t(), file:filename(), file:filename(), list(), module()) -> 'ok'. compile_xrl_yrl(Config, Source, Target, Opts, Mod) -> case needs_compile(Source, Target, []) of diff --git a/src/rebar_erlydtl_compiler.erl b/src/rebar_erlydtl_compiler.erl index 5aa67db..b90ef37 100644 --- a/src/rebar_erlydtl_compiler.erl +++ b/src/rebar_erlydtl_compiler.erl @@ -111,9 +111,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -163,7 +163,7 @@ info(help, compile) -> ]). erlydtl_opts(Config) -> - Opts = rebar_config:get(Config, erlydtl_opts, []), + Opts = rebar_state:get(Config, erlydtl_opts, []), Tuples = [{K,V} || {K,V} <- Opts], case [L || L <- Opts, is_list(L), not io_lib:printable_list(L)] of [] -> diff --git a/src/rebar_escripter.erl b/src/rebar_escripter.erl index 21dbaf8..2feb186 100644 --- a/src/rebar_escripter.erl +++ b/src/rebar_escripter.erl @@ -47,9 +47,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -59,10 +59,10 @@ init(State) -> opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). do(Config) -> - AppName = rebar_config:get_local(Config, escript_top_level_app, undefined), - App = rebar_config:get_app(Config, AppName), + AppName = rebar_state:get_local(Config, escript_top_level_app, undefined), + App = rebar_state:get_app(Config, AppName), {ok, Config1} = escriptize(Config, rebar_app_info:app_file(App)), {ok, Config1}. @@ -73,14 +73,14 @@ escriptize(Config0, AppFile) -> AppNameStr = atom_to_list(AppName), %% Get the output filename for the escript -- this may include dirs - Filename = rebar_config:get_local(Config, escript_name, AppName), + Filename = rebar_state:get_local(Config, escript_name, AppName), ok = filelib:ensure_dir(Filename), %% Look for a list of other applications (dependencies) to include %% in the output file. We then use the .app files for each of these %% to pull in all the .beam files. InclBeams = get_app_beams( - rebar_config:get_local(Config, escript_incl_apps, []), []), + rebar_state:get_local(Config, escript_incl_apps, []), []), %% Look for a list of extra files to include in the output file. %% For internal rebar-private use only. Do not use outside rebar. @@ -97,12 +97,12 @@ escriptize(Config0, AppFile) -> {ok, {"mem", ZipBin}} -> %% Archive was successfully created. Prefix that binary with our %% header and write to our escript file - Shebang = rebar_config:get(Config, escript_shebang, + Shebang = rebar_state:get(Config, escript_shebang, "#!/usr/bin/env escript\n"), - Comment = rebar_config:get(Config, escript_comment, "%%\n"), + Comment = rebar_state:get(Config, escript_comment, "%%\n"), DefaultEmuArgs = ?FMT("%%! -pa ~s/~s/ebin\n", [AppNameStr, AppNameStr]), - EmuArgs = rebar_config:get(Config, escript_emu_args, + EmuArgs = rebar_state:get(Config, escript_emu_args, DefaultEmuArgs), Script = iolist_to_binary([Shebang, Comment, EmuArgs, ZipBin]), case file:write_file(Filename, Script) of @@ -130,7 +130,7 @@ clean(Config0, AppFile) -> {Config, AppName} = rebar_app_utils:app_name(Config0, AppFile), %% Get the output filename for the escript -- this may include dirs - Filename = rebar_config:get_local(Config, escript_name, AppName), + Filename = rebar_state:get_local(Config, escript_name, AppName), rebar_file_utils:delete_each([Filename]), {ok, Config}. @@ -176,7 +176,7 @@ get_app_beams([App | Rest], Acc) -> end. get_extra(Config) -> - Extra = rebar_config:get_local(Config, escript_incl_extra, []), + Extra = rebar_state:get_local(Config, escript_incl_extra, []), lists:foldl(fun({Wildcard, Dir}, Files) -> load_files(Wildcard, Dir) ++ Files end, [], Extra). diff --git a/src/rebar_lock.erl b/src/rebar_lock.erl new file mode 100644 index 0000000..a973ccc --- /dev/null +++ b/src/rebar_lock.erl @@ -0,0 +1,13 @@ +-module(rebar_lock). + +-export([update/3]). + +create(State) -> + LockDeps = [], + ok = file:write_file("./rebar.lock", io_lib:format("~p.~n", [LockDeps])). + +update(State, App, Source) -> + New = rebar_fetch:new(rebar_app_info:dir(App), rebar_app_info:name(App), rebar_app_info:original_vsn(App), Source), + {ok, [Terms]} = file:consult("./rebar.lock"), + LockDeps = lists:keyreplace(rebar_app_info:name(App), 1, Terms, New), + ok = file:write_file("./rebar.lock", io_lib:format("~p.~n", [LockDeps])). diff --git a/src/rebar_log.erl b/src/rebar_log.erl index 1a8520f..81a2d6c 100644 --- a/src/rebar_log.erl +++ b/src/rebar_log.erl @@ -42,8 +42,7 @@ %% Public API %% =================================================================== -init(Caller, Config) -> - Verbosity = rebar_config:get_global(Config, verbose, default_level()), +init(Caller, Verbosity) -> Level = case valid_level(Verbosity) of ?ERROR_LEVEL -> error; ?WARN_LEVEL -> warn; diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl index 1779217..3d946e9 100644 --- a/src/rebar_otp_app.erl +++ b/src/rebar_otp_app.erl @@ -60,7 +60,7 @@ compile(Config, App) -> %% In general, the list of modules is an important thing to validate %% for compliance with OTP guidelines and upgrade procedures. %% However, some people prefer not to validate this list. - case rebar_config:get_local(Config3, validate_app_modules, true) of + case rebar_state:get(Config3, validate_app_modules, true) of true -> Modules = proplists:get_value(modules, AppData), {validate_modules(Dir, AppName, Modules), rebar_app_info:original_vsn(App1, AppVsn)}; @@ -138,14 +138,13 @@ preprocess(Config, Dir, AppSrcFile) -> true = code:add_path(filename:absname(filename:dirname(AppFile))), {Config2, AppFile}; - {error, Reason} -> ?ABORT("Failed to read ~s for preprocessing: ~p\n", [AppSrcFile, Reason]) end. load_app_vars(Config) -> - case rebar_config:get_local(Config, app_vars_file, undefined) of + case rebar_state:get(Config, app_vars_file, undefined) of undefined -> ?DEBUG("No app_vars_file defined.\n", []), []; diff --git a/src/rebar_provider.erl b/src/rebar_provider.erl index 39ed911..30f7d80 100644 --- a/src/rebar_provider.erl +++ b/src/rebar_provider.erl @@ -22,8 +22,8 @@ -ifdef(have_callback_support). --callback init(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). --callback do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-callback init(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). +-callback do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). -else. @@ -48,8 +48,8 @@ behaviour_info(_) -> %% %% @param ModuleName The module name. %% @param State0 The current state of the system --spec new(module(), rebar_config:config()) -> - {ok, rebar_config:config()} | relx:error(). +-spec new(module(), rebar_state:t()) -> + {ok, rebar_state:t()}. new(ModuleName, State0) when is_atom(ModuleName) -> case code:which(ModuleName) of non_existing -> @@ -62,8 +62,8 @@ new(ModuleName, State0) when is_atom(ModuleName) -> %% %% @param Provider the provider object %% @param State the current state of the system --spec do(Provider::t(), rebar_config:config()) -> - {ok, rebar_config:config()} | relx:error(). +-spec do(Provider::t(), rebar_state:t()) -> + {ok, rebar_state:t()}. do(Provider, State) -> (Provider#provider.provider_impl):do(State). @@ -82,7 +82,7 @@ format(#provider{provider_impl=Mod}) -> erlang:atom_to_list(Mod). get_target_providers(Target, State) -> - Providers = rebar_config:providers(State), + Providers = rebar_state:providers(State), TargetProviders = lists:filter(fun(#provider{name=T}) when T =:= Target-> true; (#provider{name=T}) -> diff --git a/src/rebar_prv_app_builder.erl b/src/rebar_prv_app_builder.erl index 4e5e798..e608eb1 100644 --- a/src/rebar_prv_app_builder.erl +++ b/src/rebar_prv_app_builder.erl @@ -14,9 +14,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -26,33 +26,28 @@ init(State) -> opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). do(Config) -> - Deps = rebar_config:deps_to_build(Config), - Apps = rebar_config:apps_to_build(Config), + Apps = rebar_state:apps_to_build(Config), Config1 = lists:foldl(fun(AppInfo, ConfigAcc) -> - ?INFO("Building ~p version ~p~n", [rebar_app_info:name(AppInfo) - ,rebar_app_info:original_vsn(AppInfo)]), + ?INFO("Compiling ~p ~s~n", [rebar_app_info:name(AppInfo) + ,rebar_app_info:original_vsn(AppInfo)]), {_AppInfo1, ConfigAcc1} = build(ConfigAcc, AppInfo), - ConfigAcc - end, Config, Deps++Apps), - Graph = construct_graph(Config), - Goals = rebar_config:goals(Config1), - {ok, Solve} = rlx_depsolver:solve(Graph, Goals), - - DepsDir = get_deps_dir(Config1), - LockDeps = lists:map(fun({Name, _, Source}) -> - Dir = get_deps_dir(DepsDir, Name), - {Name, Vsn} = lists:keyfind(Name, 1, Solve), - rebar_fetch:new(Dir, Name, format_vsn(Vsn), Source) - end, rebar_config:deps(Config)), - ok = file:write_file("./rebar.lock", io_lib:format("~p.~n", [LockDeps])), + ConfigAcc1 + end, Config, Apps), + + %% DepsDir = get_deps_dir(Config1), + %% LockDeps = lists:map(fun({Name, Vsn, Source}) -> + %% Dir = get_deps_dir(DepsDir, Name), + %% rebar_fetch:new(Dir, Name, Vsn, Source) + %% end, rebar_state:deps(Config)), + %% ok = file:write_file("./rebar.lock", io_lib:format("~p.~n", [LockDeps])), {ok, Config1}. build(Config, AppInfo) -> {ok, AppInfo1} = rebar_otp_app:compile(Config, AppInfo), - Config1 = rebar_config:replace_app(Config, rebar_app_info:name(AppInfo1), AppInfo1), + Config1 = rebar_state:add_app(Config, AppInfo1), rebar_erlc_compiler:compile(Config, rebar_app_info:dir(AppInfo1)), {AppInfo1, Config1}. @@ -60,35 +55,9 @@ build(Config, AppInfo) -> %% Internal functions %% =================================================================== -construct_graph(Config) -> - LibDirs = rebar_config:get_local(Config, lib_dirs, ["apps", "libs", "."]), - DepsDir = rebar_deps:get_deps_dir(Config), - Graph = rlx_depsolver:new_graph(), - Apps = rebar_app_discover:find_apps([DepsDir | LibDirs]), - lists:foldl(fun(AppInfo, GraphAcc) -> - Name = rebar_app_info:name(AppInfo), - Vsn = rebar_app_info:original_vsn(AppInfo), - C = rebar_config:new2(rebar_config:new(), rebar_app_info:dir(AppInfo)), - LocalDeps = rebar_config:get_local(C, deps, []), - PkgDeps = lists:map(fun({A, "", _}) -> - A; - ({A, ".*", _}) -> - A; - ({A, V, _}) -> - {A, V} - end, LocalDeps), - rlx_depsolver:add_package_version(GraphAcc - ,Name - ,Vsn - ,PkgDeps) - end, Graph, Apps). - get_deps_dir(Config) -> BaseDir = rebar_utils:base_dir(Config), get_deps_dir(BaseDir, deps). get_deps_dir(DepsDir, App) -> filename:join(DepsDir, atom_to_list(App)). - -format_vsn(Vsn) -> - binary_to_list(iolist_to_binary(ec_semver:format(Vsn))). diff --git a/src/rebar_prv_app_discovery.erl b/src/rebar_prv_app_discovery.erl new file mode 100644 index 0000000..e3144aa --- /dev/null +++ b/src/rebar_prv_app_discovery.erl @@ -0,0 +1,36 @@ +%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ts=4 sw=4 et + +-module(rebar_prv_app_discovery). + +-behaviour(rebar_provider). + +-export([init/1, + do/1]). + +-include("rebar.hrl"). + +-define(PROVIDER, app_discovery). +-define(DEPS, []). + +%% =================================================================== +%% Public API +%% =================================================================== + +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. +init(State) -> + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, + provider_impl = ?MODULE, + bare = false, + deps = ?DEPS, + example = "", + short_desc = "", + desc = "", + opts = []}), + {ok, State1}. + +-spec do(rebar_state:t()) -> {ok, rebar_state:t()}. +do(State) -> + LibDirs = rebar_state:get(State, lib_dirs, ?DEFAULT_LIB_DIRS), + State1 = rebar_app_discover:do(State, ["deps" | LibDirs]), + {ok, State1}. diff --git a/src/rebar_prv_release.erl b/src/rebar_prv_release.erl index 77a2353..d084ad5 100644 --- a/src/rebar_prv_release.erl +++ b/src/rebar_prv_release.erl @@ -17,9 +17,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -29,8 +29,8 @@ init(State) -> opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). do(Config) -> - RelxConfig = rebar_config:get_local(Config, relx, []), + RelxConfig = rebar_state:get_local(Config, relx, []), relx:main("release"), {ok, Config}. diff --git a/src/rebar_prv_tar.erl b/src/rebar_prv_tar.erl index 775e3b9..44d83db 100644 --- a/src/rebar_prv_tar.erl +++ b/src/rebar_prv_tar.erl @@ -17,9 +17,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -29,8 +29,8 @@ init(State) -> opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). do(Config) -> - RelxConfig = rebar_config:get_local(Config, relx, []), + RelxConfig = rebar_state:get_local(Config, relx, []), relx:main("release tar"), {ok, Config}. diff --git a/src/rebar_prv_update.erl b/src/rebar_prv_update.erl index ef6270a..f48b507 100644 --- a/src/rebar_prv_update.erl +++ b/src/rebar_prv_update.erl @@ -17,9 +17,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -29,13 +29,13 @@ init(State) -> opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). do(Config) -> - [Name] = rebar_config:command_args(Config), + [Name] = rebar_state:command_args(Config), ?INFO("Updating ~s~n", [Name]), DepsDir = rebar_deps:get_deps_dir(Config), - Deps = rebar_config:get_local(Config, deps, []), + Deps = rebar_state:get_local(Config, deps, []), {_, _, Source} = lists:keyfind(list_to_atom(Name), 1, Deps), TargetDir = rebar_deps:get_deps_dir(DepsDir, Name), rebar_fetch:update_source1(TargetDir, Source), @@ -43,14 +43,9 @@ do(Config) -> [App] = rebar_app_discover:find_apps([TargetDir]), {ok, AppInfo1} = rebar_otp_app:compile(Config, App), - Config1 = rebar_config:replace_app(Config, rebar_app_info:name(AppInfo1), AppInfo1), + Config1 = rebar_state:replace_app(Config, rebar_app_info:name(AppInfo1), AppInfo1), rebar_erlc_compiler:compile(Config, rebar_app_info:dir(AppInfo1)), - update_lock_file(Config, AppInfo1, Source), - {ok, Config}. + %update_lock_file(Config, AppInfo1, Source), -update_lock_file(Config, App, Source) -> - New = rebar_fetch:new(rebar_app_info:dir(App), rebar_app_info:name(App), rebar_app_info:original_vsn(App), Source), - {ok, [Terms]} = file:consult("./rebar.lock"), - LockDeps = lists:keyreplace(rebar_app_info:name(App), 1, Terms, New), - ok = file:write_file("./rebar.lock", io_lib:format("~p.~n", [LockDeps])). + {ok, Config}. diff --git a/src/rebar_shell.erl b/src/rebar_shell.erl index 97ac23e..fdd8523 100644 --- a/src/rebar_shell.erl +++ b/src/rebar_shell.erl @@ -42,9 +42,9 @@ %% Public API %% =================================================================== --spec init(rebar_config:config()) -> {ok, rebar_config:config()}. +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER, + State1 = rebar_state:add_provider(State, #provider{name = ?PROVIDER, provider_impl = ?MODULE, bare = false, deps = ?DEPS, @@ -54,7 +54,7 @@ init(State) -> opts = []}), {ok, State1}. --spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error(). +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error(). do(Config) -> shell(), {ok, Config}. diff --git a/src/rebar_state.erl b/src/rebar_state.erl new file mode 100644 index 0000000..62448ed --- /dev/null +++ b/src/rebar_state.erl @@ -0,0 +1,159 @@ +-module(rebar_state). + +-export([new/0, new/1, new/2, new/3, + get/2, get/3, set/3, + command_args/1, command_args/2, + + set_skip_dir/2, is_skip_dir/2, reset_skip_dirs/1, + create_logic_providers/2, + + add_app/2, apps_to_build/1, apps_to_build/2, + deps_to_build/1, deps_to_build/2, + + providers/1, providers/2, add_provider/2]). + +-include("rebar.hrl"). + +-ifdef(namespaced_types). +%% dict:dict() exists starting from Erlang 17. +-type rebar_dict() :: dict:dict(term(), term()). +-else. +%% dict() has been obsoleted in Erlang 17 and deprecated in 18. +-type rebar_dict() :: dict(). +-endif. + +-record(state_t, {dir :: file:filename(), + opts = [] :: list(), + local_opts = [] :: list(), + config = new_globals() :: rebar_dict(), + + envs = new_env() :: rebar_dict(), + command_args = [] :: list(), + + goals = [], + providers = [], + apps_to_build = [], + deps_to_build = [], + skip_dirs = new_skip_dirs() :: rebar_dict() }). + +-export_type([t/0]). + +-opaque t() :: #state_t{}. + +-spec new() -> t(). +new() -> + #state_t{dir = rebar_utils:get_cwd()}. + +-spec new(list()) -> t(). +new(Config) when is_list(Config) -> + #state_t { dir = rebar_utils:get_cwd(), + opts = Config }. + +-spec new(t(), list()) -> t(). +new(ParentState=#state_t{}, Config) -> + %% Load terms from rebar.config, if it exists + Dir = rebar_utils:get_cwd(), + new(ParentState, Config, Dir). + +-spec new(t(), list(), file:name()) -> t(). +new(ParentState, Config, Dir) -> + _Opts = ParentState#state_t.opts, + LocalOpts = case rebar_config:consult_file(?LOCK_FILE) of + {ok, [D]} -> + [{lock_deps, D} | Config]; + _ -> + Config + end, + + ProviderModules = [], + create_logic_providers(ProviderModules, ParentState#state_t{dir=Dir + ,opts=LocalOpts}). + +get(State, Key) -> + proplists:get_value(Key, State#state_t.opts). + +get(State, Key, Default) -> + proplists:get_value(Key, State#state_t.opts, Default). + +get_local(State, Key, Default) -> + proplists:get_value(Key, State#state_t.local_opts, Default). + +set(State, Key, Value) -> + Opts = proplists:delete(Key, State#state_t.opts), + State#state_t { opts = [{Key, Value} | Opts] }. + +set_skip_dir(State, Dir) -> + OldSkipDirs = State#state_t.skip_dirs, + NewSkipDirs = case is_skip_dir(State, Dir) of + false -> + ?DEBUG("Adding skip dir: ~s\n", [Dir]), + dict:store(Dir, true, OldSkipDirs); + true -> + OldSkipDirs + end, + State#state_t{skip_dirs = NewSkipDirs}. + +is_skip_dir(State, Dir) -> + dict:is_key(Dir, State#state_t.skip_dirs). + +reset_skip_dirs(State) -> + State#state_t{skip_dirs = new_skip_dirs()}. + +command_args(#state_t{command_args=CmdArgs}) -> + CmdArgs. + +command_args(State, CmdArgs) -> + State#state_t{command_args=CmdArgs}. + +get_app(#state_t{apps_to_build=Apps}, Name) -> + lists:keyfind(Name, 2, Apps). + +apps_to_build(#state_t{apps_to_build=Apps}) -> + Apps. + +apps_to_build(State, Apps) -> + State#state_t{apps_to_build=Apps}. + +deps_to_build(#state_t{deps_to_build=Deps}) -> + Deps. + +deps_to_build(State, Deps) -> + State#state_t{deps_to_build=Deps}. + +add_app(State=#state_t{apps_to_build=Apps}, App) -> + State#state_t{apps_to_build=[App | Apps]}. + +replace_app(State=#state_t{apps_to_build=Apps}, Name, App) -> + Apps1 = lists:keydelete(Name, 2, Apps), + State#state_t{apps_to_build=[App | Apps1]}. + +providers(#state_t{providers=Providers}) -> + Providers. + +providers(State, NewProviders) -> + State#state_t{providers=NewProviders}. + +goals(#state_t{goals=Goals}) -> + Goals. + +goals(State, Goals) -> + State#state_t{goals=Goals}. + +add_provider(State=#state_t{providers=Providers}, Provider) -> + State#state_t{providers=[Provider | Providers]}. + +create_logic_providers(ProviderModules, State0) -> + lists:foldl(fun(ProviderMod, Acc) -> + {ok, State1} = rebar_provider:new(ProviderMod, Acc), + State1 + end, State0, ProviderModules). + +%% =================================================================== +%% Internal functions +%% =================================================================== + +new_globals() -> dict:new(). + +new_env() -> dict:new(). + +new_skip_dirs() -> dict:new(). diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 8474a26..6b12e99 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -61,7 +61,6 @@ erl_opts/1, src_dirs/1, ebin_dir/0, - base_dir/1, processing_base_dir/1, processing_base_dir/2, patch_env/2]). @@ -129,7 +128,7 @@ sh_send(Command0, String, Options0) -> %% Val = string() | false %% sh(Command0, Options0) -> - ?INFO("sh info:\n\tcwd: ~p\n\tcmd: ~s\n", [get_cwd(), Command0]), + ?DEBUG("sh info:\n\tcwd: ~p\n\tcmd: ~s\n", [get_cwd(), Command0]), ?DEBUG("\topts: ~p\n", [Options0]), DefaultOptions = [use_stdout, abort_on_error], @@ -236,12 +235,12 @@ expand_env_variable(InStr, VarName, RawVarValue) -> vcs_vsn(Config, Vsn, Dir) -> Key = {Vsn, Dir}, - Cache = rebar_config:get_xconf(Config, vsn_cache), + Cache = rebar_state:get(Config, vsn_cache, dict:new()), case dict:find(Key, Cache) of error -> VsnString = vcs_vsn_1(Vsn, Dir), Cache1 = dict:store(Key, VsnString, Cache), - Config1 = rebar_config:set_xconf(Config, vsn_cache, Cache1), + Config1 = rebar_state:set(Config, vsn_cache, Cache1), {Config1, VsnString}; {ok, VsnString} -> {Config, VsnString} @@ -251,27 +250,27 @@ get_deprecated_global(Config, OldOpt, NewOpt, When) -> get_deprecated_global(Config, OldOpt, NewOpt, undefined, When). get_deprecated_global(Config, OldOpt, NewOpt, Default, When) -> - get_deprecated_3(fun rebar_config:get_global/3, + get_deprecated_3(fun rebar_state:get/3, Config, OldOpt, NewOpt, Default, When). get_experimental_global(Config, Opt, Default) -> - get_experimental_3(fun rebar_config:get_global/3, Config, Opt, Default). + get_experimental_3(fun rebar_state:get/3, Config, Opt, Default). get_experimental_local(Config, Opt, Default) -> - get_experimental_3(fun rebar_config:get_local/3, Config, Opt, Default). + get_experimental_3(fun rebar_state:get/3, Config, Opt, Default). get_deprecated_list(Config, OldOpt, NewOpt, When) -> get_deprecated_list(Config, OldOpt, NewOpt, undefined, When). get_deprecated_list(Config, OldOpt, NewOpt, Default, When) -> - get_deprecated_3(fun rebar_config:get_list/3, + get_deprecated_3(fun rebar_state:get_list/3, Config, OldOpt, NewOpt, Default, When). get_deprecated_local(Config, OldOpt, NewOpt, When) -> get_deprecated_local(Config, OldOpt, NewOpt, undefined, When). get_deprecated_local(Config, OldOpt, NewOpt, Default, When) -> - get_deprecated_3(fun rebar_config:get_local/3, + get_deprecated_3(fun rebar_state:get/3, Config, OldOpt, NewOpt, Default, When). deprecated(Old, New, Opts, When) when is_list(Opts) -> @@ -282,7 +281,7 @@ deprecated(Old, New, Opts, When) when is_list(Opts) -> ok end; deprecated(Old, New, Config, When) -> - case rebar_config:get(Config, Old, undefined) of + case rebar_state:get(Config, Old, undefined) of undefined -> ok; _ -> @@ -319,11 +318,11 @@ delayed_halt(Code) -> end. %% @doc Return list of erl_opts --spec erl_opts(rebar_config:config()) -> list(). +-spec erl_opts(rebar_state:config()) -> list(). erl_opts(Config) -> - RawErlOpts = filter_defines(rebar_config:get(Config, erl_opts, []), []), + RawErlOpts = filter_defines(rebar_state:get(Config, erl_opts, []), []), Defines = [{d, list_to_atom(D)} || - D <- rebar_config:get_xconf(Config, defines, [])], + D <- rebar_state:get(Config, defines, [])], Opts = Defines ++ RawErlOpts, case proplists:is_defined(no_debug_info, Opts) of true -> @@ -341,26 +340,23 @@ src_dirs(SrcDirs) -> ebin_dir() -> filename:join(get_cwd(), "ebin"). -base_dir(Config) -> - rebar_config:get_xconf(Config, base_dir). - -processing_base_dir(Config) -> +processing_base_dir(State) -> Cwd = rebar_utils:get_cwd(), - processing_base_dir(Config, Cwd). + processing_base_dir(State, Cwd). -processing_base_dir(Config, Dir) -> +processing_base_dir(State, Dir) -> AbsDir = filename:absname(Dir), - AbsDir =:= base_dir(Config). + AbsDir =:= rebar_state:get(State, base_dir). %% @doc Returns the list of environment variables including 'REBAR' which %% points to the rebar executable used to execute the currently running %% command. The environment is not modified if rebar was invoked %% programmatically. --spec patch_env(rebar_config:config(), [{string(), string()}]) +-spec patch_env(rebar_state:config(), [{string(), string()}]) -> [{string(), string()}]. patch_env(Config, []) -> %% If we reached an empty list, the env did not contain the REBAR variable. - case rebar_config:get_xconf(Config, escript, "") of + case rebar_state:get(Config, escript, "") of "" -> % rebar was invoked programmatically []; Path -> -- cgit v1.1