summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJared Morrow <jared@basho.com>2014-04-24 07:15:10 -0600
committerJared Morrow <jared@basho.com>2014-04-24 07:15:10 -0600
commita838a2e4878887e84190070d589248b74edd12c0 (patch)
tree65754ba961d56a4dac18e23e5a55a06f6af7e4bd
parent8edaa08ba6b051f49ec3631ca1aa424573c3dac6 (diff)
parent99fe270e59b44526b43f2b8d93d51b20d45b62d3 (diff)
Merge pull request #268 from tuncer/code-path-regression
Fix #267 (code path regression)
-rw-r--r--.gitignore17
-rw-r--r--inttest/code_path_no_recurse/code_path_no_recurse_rt.erl19
-rw-r--r--inttest/code_path_no_recurse/deps/bazdep/src/bazdep.app.src12
-rw-r--r--inttest/code_path_no_recurse/deps/bazdep/src/bazdep.erl6
-rw-r--r--inttest/code_path_no_recurse/deps/bazdep/test/bazdep_tests.erl5
-rw-r--r--inttest/code_path_no_recurse/deps/foodep/rebar.config1
-rw-r--r--inttest/code_path_no_recurse/deps/foodep/src/foodep.app.src12
-rw-r--r--inttest/code_path_no_recurse/deps/foodep/src/foodep.erl6
-rw-r--r--inttest/code_path_no_recurse/deps/foodep/test/foodep_tests.erl5
-rw-r--r--inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.app.src12
-rw-r--r--inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.erl6
-rw-r--r--inttest/code_path_no_recurse/rebar.config1
-rw-r--r--inttest/code_path_no_recurse/src/codepath.app.src12
-rw-r--r--inttest/code_path_no_recurse/src/codepath.erl6
-rw-r--r--inttest/code_path_no_recurse/test/codepath_tests.erl12
-rw-r--r--src/rebar_core.erl168
16 files changed, 210 insertions, 90 deletions
diff --git a/.gitignore b/.gitignore
index 165948e..15668a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,11 @@
-*.beam
-rebar
+/ebin/*.beam
+/rebar
*~
*.orig
.*.swp
-rt.work
-.test
-dialyzer_warnings
-rebar.cmd
-.eunit
-deps
-.rebar/*
+/rt.work
+/dialyzer_warnings
+/rebar.cmd
+/.eunit
+/deps
+/.rebar
diff --git a/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl b/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl
new file mode 100644
index 0000000..d884bcc
--- /dev/null
+++ b/inttest/code_path_no_recurse/code_path_no_recurse_rt.erl
@@ -0,0 +1,19 @@
+-module(code_path_no_recurse_rt).
+-export([files/0,
+ run/1]).
+
+files() ->
+ [
+ {copy, "../../rebar", "rebar"},
+ {copy, "rebar.config", "rebar.config"},
+ {copy, "src", "src"},
+ {copy, "test", "test"},
+ {copy, "deps", "deps"}
+ ].
+
+run(_Dir) ->
+ retest:log(info, "Compile project~n"),
+ {ok, _} = retest:sh("./rebar -v compile"),
+ retest:log(info, "Run eunit with referenced deps on the code path~n"),
+ {ok, _} = retest:sh("./rebar -v eunit"),
+ ok.
diff --git a/inttest/code_path_no_recurse/deps/bazdep/src/bazdep.app.src b/inttest/code_path_no_recurse/deps/bazdep/src/bazdep.app.src
new file mode 100644
index 0000000..7f7b3f9
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/bazdep/src/bazdep.app.src
@@ -0,0 +1,12 @@
+{application, bazdep,
+ [
+ {description, ""},
+ {vsn, "1"},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib
+ ]},
+ {mod, {bazdep, []}},
+ {env, []}
+ ]}.
diff --git a/inttest/code_path_no_recurse/deps/bazdep/src/bazdep.erl b/inttest/code_path_no_recurse/deps/bazdep/src/bazdep.erl
new file mode 100644
index 0000000..aef4cf3
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/bazdep/src/bazdep.erl
@@ -0,0 +1,6 @@
+-module(bazdep).
+
+-export([bazdep/0]).
+
+bazdep() ->
+ bazdep.
diff --git a/inttest/code_path_no_recurse/deps/bazdep/test/bazdep_tests.erl b/inttest/code_path_no_recurse/deps/bazdep/test/bazdep_tests.erl
new file mode 100644
index 0000000..b5190f6
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/bazdep/test/bazdep_tests.erl
@@ -0,0 +1,5 @@
+-module(bazdep_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+bazdep_test() ->
+ ?assert(bazdep:bazdep() =:= bazdep).
diff --git a/inttest/code_path_no_recurse/deps/foodep/rebar.config b/inttest/code_path_no_recurse/deps/foodep/rebar.config
new file mode 100644
index 0000000..cdaf168
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/foodep/rebar.config
@@ -0,0 +1 @@
+{deps, [{bazdep, "1"}]}.
diff --git a/inttest/code_path_no_recurse/deps/foodep/src/foodep.app.src b/inttest/code_path_no_recurse/deps/foodep/src/foodep.app.src
new file mode 100644
index 0000000..c0642fb
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/foodep/src/foodep.app.src
@@ -0,0 +1,12 @@
+{application, foodep,
+ [
+ {description, ""},
+ {vsn, "1"},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib
+ ]},
+ {mod, {foodep, []}},
+ {env, []}
+ ]}.
diff --git a/inttest/code_path_no_recurse/deps/foodep/src/foodep.erl b/inttest/code_path_no_recurse/deps/foodep/src/foodep.erl
new file mode 100644
index 0000000..3d43d0e
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/foodep/src/foodep.erl
@@ -0,0 +1,6 @@
+-module(foodep).
+
+-export([foodep/0]).
+
+foodep() ->
+ bazdep:bazdep() =:= bazdep.
diff --git a/inttest/code_path_no_recurse/deps/foodep/test/foodep_tests.erl b/inttest/code_path_no_recurse/deps/foodep/test/foodep_tests.erl
new file mode 100644
index 0000000..66d7b8b
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/foodep/test/foodep_tests.erl
@@ -0,0 +1,5 @@
+-module(foodep_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+foodep_test() ->
+ ?assert(foodep:foodep()).
diff --git a/inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.app.src b/inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.app.src
new file mode 100644
index 0000000..d0bc233
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.app.src
@@ -0,0 +1,12 @@
+{application, unuseddep,
+ [
+ {description, ""},
+ {vsn, "1"},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib
+ ]},
+ {mod, {unuseddep, []}},
+ {env, []}
+ ]}.
diff --git a/inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.erl b/inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.erl
new file mode 100644
index 0000000..a990345
--- /dev/null
+++ b/inttest/code_path_no_recurse/deps/unuseddep/src/unuseddep.erl
@@ -0,0 +1,6 @@
+-module(unuseddep).
+
+-export([unuseddep/0]).
+
+unuseddep() ->
+ unuseddep.
diff --git a/inttest/code_path_no_recurse/rebar.config b/inttest/code_path_no_recurse/rebar.config
new file mode 100644
index 0000000..4b358de
--- /dev/null
+++ b/inttest/code_path_no_recurse/rebar.config
@@ -0,0 +1 @@
+{deps, [{foodep, "1"}]}.
diff --git a/inttest/code_path_no_recurse/src/codepath.app.src b/inttest/code_path_no_recurse/src/codepath.app.src
new file mode 100644
index 0000000..3aa200f
--- /dev/null
+++ b/inttest/code_path_no_recurse/src/codepath.app.src
@@ -0,0 +1,12 @@
+{application, codepath,
+ [
+ {description, ""},
+ {vsn, "1"},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib
+ ]},
+ {mod, {codepath, []}},
+ {env, []}
+ ]}.
diff --git a/inttest/code_path_no_recurse/src/codepath.erl b/inttest/code_path_no_recurse/src/codepath.erl
new file mode 100644
index 0000000..df4e6b0
--- /dev/null
+++ b/inttest/code_path_no_recurse/src/codepath.erl
@@ -0,0 +1,6 @@
+-module(codepath).
+
+-export([codepath/0]).
+
+codepath() ->
+ foodep:foodep().
diff --git a/inttest/code_path_no_recurse/test/codepath_tests.erl b/inttest/code_path_no_recurse/test/codepath_tests.erl
new file mode 100644
index 0000000..01a1d2a
--- /dev/null
+++ b/inttest/code_path_no_recurse/test/codepath_tests.erl
@@ -0,0 +1,12 @@
+-module(codepath_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+codepath_test() ->
+ ?assertEqual({module, codepath}, code:ensure_loaded(codepath)),
+ ?assertEqual({module, foodep}, code:ensure_loaded(foodep)),
+ ?assertEqual({module, bazdep}, code:ensure_loaded(bazdep)),
+ ?assert(codepath:codepath()).
+
+unuseddep_test() ->
+ ?assertEqual(non_existing, code:which(unuseddep)),
+ ?assertEqual({error, nofile}, code:ensure_loaded(unuseddep)).
diff --git a/src/rebar_core.erl b/src/rebar_core.erl
index f54147f..3a4f205 100644
--- a/src/rebar_core.erl
+++ b/src/rebar_core.erl
@@ -88,7 +88,7 @@ process_commands([Command | Rest], ParentConfig) ->
%% path from inside a subdirectory.
true = rebar_utils:expand_code_path(),
{ParentConfig2, _DirSet} = process_dir(rebar_utils:get_cwd(),
- ParentConfig1, Command,
+ Command, ParentConfig1,
sets:new()),
case get_operations(ParentConfig2) of
Operations ->
@@ -117,18 +117,13 @@ process_commands([Command | Rest], ParentConfig) ->
end,
process_commands(Rest, ParentConfig4).
-process_dir(Dir, ParentConfig, Command, DirSet) ->
+process_dir(Dir, Command, ParentConfig, DirSet) ->
case filelib:is_dir(Dir) of
false ->
?WARN("Skipping non-existent sub-dir: ~p\n", [Dir]),
{ParentConfig, DirSet};
true ->
- maybe_process_dir(Dir, ParentConfig, Command, DirSet)
- end.
-
-maybe_process_dir(Dir, ParentConfig, Command, DirSet) ->
- case should_cd_into_dir(Dir, ParentConfig, Command) of
- true ->
+ WouldCd = would_cd_into_dir(Dir, Command, ParentConfig),
ok = file:set_cwd(Dir),
Config = maybe_load_local_config(Dir, ParentConfig),
@@ -143,21 +138,27 @@ maybe_process_dir(Dir, ParentConfig, Command, DirSet) ->
%% set of modules to process this dir.
{ok, AvailModuleSets} = application:get_env(rebar, modules),
ModuleSet = choose_module_set(AvailModuleSets, Dir),
- skip_or_process_dir(ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet);
+ skip_or_process_dir(Dir, Command, Config, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd)
+ end.
+
+would_cd_into_dir(Dir, Command, Config) ->
+ case would_cd_into_dir1(Dir, Command, Config) of
+ true ->
+ would_cd;
false ->
- {ParentConfig, DirSet}
+ would_not_cd
end.
-should_cd_into_dir(Dir, Config, Command) ->
+would_cd_into_dir1(Dir, Command, Config) ->
rebar_utils:processing_base_dir(Config, Dir) orelse
rebar_config:is_recursive(Config) orelse
- is_recursive_command(Config, Command) orelse
+ is_recursive_command(Command, Config) orelse
is_generate_in_rel_dir(Command, Dir).
%% Check whether the command is part of the built-in (or extended via
%% rebar.config) list of default-recursive commands.
-is_recursive_command(Config, Command) ->
+is_recursive_command(Command, Config) ->
{ok, AppCmds} = application:get_env(rebar, recursive_cmds),
ConfCmds = rebar_config:get_local(Config, recursive_cmds, []),
RecursiveCmds = AppCmds ++ ConfCmds,
@@ -180,46 +181,46 @@ is_generate_in_rel_dir(generate, Dir) ->
is_generate_in_rel_dir(_, _) ->
false.
-skip_or_process_dir({[], undefined}=ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet) ->
- process_dir1(Dir, Command, DirSet, Config, CurrentCodePath, ModuleSet);
-skip_or_process_dir({_, ModuleSetFile}=ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet) ->
- case lists:suffix(".app.src", ModuleSetFile)
- orelse lists:suffix(".app", ModuleSetFile) of
+skip_or_process_dir(Dir, Command, Config, DirSet, CurrentCodePath,
+ {[], undefined}=ModuleSet, WouldCd) ->
+ process_dir1(Dir, Command, Config, DirSet, CurrentCodePath, ModuleSet,
+ WouldCd);
+skip_or_process_dir(Dir, Command, Config, DirSet, CurrentCodePath,
+ {_, File}=ModuleSet, WouldCd) ->
+ case lists:suffix(".app.src", File)
+ orelse lists:suffix(".app", File) of
true ->
%% .app or .app.src file, check if is_skipped_app
- skip_or_process_dir1(ModuleSetFile, ModuleSet,
- Config, CurrentCodePath, Dir,
- Command, DirSet);
+ skip_or_process_dir1(Dir, Command, Config, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd, File);
false ->
%% not an app dir, no need to consider apps=/skip_apps=
- process_dir1(Dir, Command, DirSet, Config,
- CurrentCodePath, ModuleSet)
+ process_dir1(Dir, Command, Config, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd)
end.
-skip_or_process_dir1(AppFile, ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet) ->
+skip_or_process_dir1(Dir, Command, Config, DirSet, CurrentCodePath, ModuleSet,
+ WouldCd, AppFile) ->
case rebar_app_utils:is_skipped_app(Config, AppFile) of
{Config1, {true, _SkippedApp}} when Command == 'update-deps' ->
%% update-deps does its own app skipping. Unfortunately there's no
%% way to signal this to rebar_core, so we have to explicitly do it
%% here... Otherwise if you use app=, it'll skip the toplevel
%% directory and nothing will be updated.
- process_dir1(Dir, Command, DirSet, Config1,
- CurrentCodePath, ModuleSet);
+ process_dir1(Dir, Command, Config1, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd);
{Config1, {true, SkippedApp}} ->
?DEBUG("Skipping app: ~p~n", [SkippedApp]),
- Config2 = increment_operations(Config1),
- {Config2, DirSet};
+ {increment_operations(Config1), DirSet};
{Config1, false} ->
- process_dir1(Dir, Command, DirSet, Config1,
- CurrentCodePath, ModuleSet)
+ process_dir1(Dir, Command, Config1, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd)
end.
-process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
- {DirModules, ModuleSetFile}) ->
+process_dir1(Dir, Command, Config, DirSet, CurrentCodePath,
+ {DirModules, File}, WouldCd) ->
Config0 = rebar_config:set_xconf(Config, current_command, Command),
+
%% Get the list of modules for "any dir". This is a catch-all list
%% of modules that are processed in addition to modules associated
%% with this directory type. These any_dir modules are processed
@@ -230,8 +231,7 @@ process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
%% Invoke 'preprocess' on the modules -- this yields a list of other
%% directories that should be processed _before_ the current one.
- {Config1, Predirs} = acc_modules(Modules, preprocess, Config0,
- ModuleSetFile),
+ {Config1, Predirs} = acc_modules(Modules, preprocess, Config0, File),
%% Remember associated pre-dirs (used for plugin lookup)
PredirsAssoc = remember_cwd_predirs(Dir, Predirs),
@@ -239,55 +239,33 @@ process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
%% Get the list of plug-in modules from rebar.config. These
%% modules may participate in preprocess and postprocess.
{ok, PluginModules} = plugin_modules(Config1, PredirsAssoc),
+ AllModules = Modules ++ PluginModules,
- {Config2, PluginPredirs} = acc_modules(PluginModules, preprocess,
- Config1, ModuleSetFile),
+ {Config2, PluginPredirs} = acc_modules(PluginModules, preprocess, Config1,
+ File),
AllPredirs = Predirs ++ PluginPredirs,
?DEBUG("Predirs: ~p\n", [AllPredirs]),
- {Config3, DirSet2} = process_each(AllPredirs, Command, Config2,
- ModuleSetFile, DirSet),
+ {Config3, DirSet2} = process_each(AllPredirs, Command, Config2, DirSet,
+ File),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
ok = file:set_cwd(Dir),
- %% Check that this directory is not on the skip list
- Config7 = case rebar_config:is_skip_dir(Config3, Dir) of
- true ->
- %% Do not execute the command on the directory, as some
- %% module has requested a skip on it.
- ?INFO("Skipping ~s in ~s\n", [Command, Dir]),
- Config3;
-
- false ->
- %% Check for and get command specific environments
- {Config4, Env} = setup_envs(Config3, Modules),
-
- %% Execute any before_command plugins on this directory
- Config5 = execute_pre(Command, PluginModules,
- Config4, ModuleSetFile, Env),
-
- %% Execute the current command on this directory
- Config6 = execute(Command, Modules ++ PluginModules,
- Config5, ModuleSetFile, Env),
-
- %% Execute any after_command plugins on this directory
- execute_post(Command, PluginModules,
- Config6, ModuleSetFile, Env)
- end,
+ %% Maybe apply command to Dir
+ Config4 = maybe_execute(Dir, Command, Config3, Modules, PluginModules,
+ AllModules, File, WouldCd),
%% Mark the current directory as processed
DirSet3 = sets:add_element(Dir, DirSet2),
%% Invoke 'postprocess' on the modules. This yields a list of other
%% directories that should be processed _after_ the current one.
- {Config8, Postdirs} = acc_modules(Modules ++ PluginModules, postprocess,
- Config7, ModuleSetFile),
+ {Config5, Postdirs} = acc_modules(AllModules, postprocess, Config4, File),
?DEBUG("Postdirs: ~p\n", [Postdirs]),
- Res = process_each(Postdirs, Command, Config8,
- ModuleSetFile, DirSet3),
+ Res = process_each(Postdirs, Command, Config5, DirSet3, File),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
@@ -300,6 +278,33 @@ process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
%% Return the updated {config, dirset} as result
Res.
+maybe_execute(Dir, Command, Config, Modules, PluginModules, AllModules, File,
+ would_cd) ->
+ %% Check that this directory is not on the skip list
+ case rebar_config:is_skip_dir(Config, Dir) of
+ true ->
+ %% Do not execute the command on the directory, as some
+ %% module has requested a skip on it.
+ ?INFO("Skipping ~s in ~s\n", [Command, Dir]),
+ Config;
+
+ false ->
+ %% Check for and get command specific environments
+ {Config1, Env} = setup_envs(Config, Modules),
+
+ %% Execute any before_command plugins on this directory
+ Config2 = execute_pre(Command, PluginModules, Config1, File, Env),
+
+ %% Execute the current command on this directory
+ Config3 = execute(Command, AllModules, Config2, File, Env),
+
+ %% Execute any after_command plugins on this directory
+ execute_post(Command, PluginModules, Config3, File, Env)
+ end;
+maybe_execute(_Dir, _Command, Config, _Modules, _PluginModules, _AllModules,
+ _File, would_not_cd) ->
+ Config.
+
remember_cwd_predirs(Cwd, Predirs) ->
Store = fun(Dir, Dict) ->
case dict:find(Dir, Dict) of
@@ -330,21 +335,21 @@ maybe_load_local_config(Dir, ParentConfig) ->
%% Given a list of directories and a set of previously processed directories,
%% process each one we haven't seen yet
%%
-process_each([], _Command, Config, _ModuleSetFile, DirSet) ->
+process_each([], _Command, Config, DirSet, _File) ->
%% reset cached (setup_env) envs
Config1 = rebar_config:reset_envs(Config),
{Config1, DirSet};
-process_each([Dir | Rest], Command, Config, ModuleSetFile, DirSet) ->
+process_each([Dir | Rest], Command, Config, DirSet, File) ->
case sets:is_element(Dir, DirSet) of
true ->
?DEBUG("Skipping ~s; already processed!\n", [Dir]),
- process_each(Rest, Command, Config, ModuleSetFile, DirSet);
+ process_each(Rest, Command, Config, DirSet, File);
false ->
- {Config1, DirSet2} = process_dir(Dir, Config, Command, DirSet),
+ {Config1, DirSet2} = process_dir(Dir, Command, Config, DirSet),
Config2 = rebar_config:clean_config(Config, Config1),
%% reset cached (setup_env) envs
Config3 = rebar_config:reset_envs(Config2),
- process_each(Rest, Command, Config3, ModuleSetFile, DirSet2)
+ process_each(Rest, Command, Config3, DirSet2, File)
end.
%%
@@ -378,20 +383,21 @@ execute_post(Command, Modules, Config, ModuleFile, Env) ->
execute_plugin_hook(Hook, Command, Modules, Config, ModuleFile, Env) ->
HookFunction = list_to_atom(Hook ++ atom_to_list(Command)),
- execute(HookFunction, Modules, Config, ModuleFile, Env).
+ execute(HookFunction, hook, Modules, Config, ModuleFile, Env).
%%
%% Execute a command across all applicable modules
%%
execute(Command, Modules, Config, ModuleFile, Env) ->
+ execute(Command, not_a_hook, Modules, Config, ModuleFile, Env).
+
+execute(Command, Type, Modules, Config, ModuleFile, Env) ->
case select_modules(Modules, Command, []) of
[] ->
- Cmd = atom_to_list(Command),
- case lists:prefix("pre_", Cmd)
- orelse lists:prefix("post_", Cmd) of
- true ->
+ case Type of
+ hook ->
ok;
- false ->
+ not_a_hook ->
?WARN("'~p' command does not apply to directory ~s\n",
[Command, rebar_utils:get_cwd()])
end,