diff --git a/inttest/tdeps3/a.erl b/inttest/tdeps3/a.erl new file mode 100644 index 0000000..5a387eb --- /dev/null +++ b/inttest/tdeps3/a.erl @@ -0,0 +1,3 @@ +-module({{module}}). + +-include_lib("{{dep}}/include/{{dep}}.hrl"). diff --git a/inttest/tdeps3/a.rebar.config b/inttest/tdeps3/a.rebar.config new file mode 100644 index 0000000..19b8ef8 --- /dev/null +++ b/inttest/tdeps3/a.rebar.config @@ -0,0 +1,4 @@ +{deps, [ + {b, "1", {git, "../repo/b"}}, + {f, "1", {git, "../repo/f"}} +]}. diff --git a/inttest/tdeps3/b.hrl b/inttest/tdeps3/b.hrl new file mode 100644 index 0000000..efbeab1 --- /dev/null +++ b/inttest/tdeps3/b.hrl @@ -0,0 +1 @@ +-include_lib("c/include/c.hrl"). diff --git a/inttest/tdeps3/b.rebar.config b/inttest/tdeps3/b.rebar.config new file mode 100644 index 0000000..d1ccae2 --- /dev/null +++ b/inttest/tdeps3/b.rebar.config @@ -0,0 +1,5 @@ +{deps, [ + {c, "1", {git, "../repo/c"}} +]}. + +{lib_dirs, [apps]}. diff --git a/inttest/tdeps3/c.hrl b/inttest/tdeps3/c.hrl new file mode 100644 index 0000000..cc87fff --- /dev/null +++ b/inttest/tdeps3/c.hrl @@ -0,0 +1 @@ +-include_lib("d/include/d.hrl"). diff --git a/inttest/tdeps3/c.rebar.config b/inttest/tdeps3/c.rebar.config new file mode 100644 index 0000000..b590771 --- /dev/null +++ b/inttest/tdeps3/c.rebar.config @@ -0,0 +1 @@ +{deps, [{d, "1", {git, "../repo/d"}}]}. diff --git a/inttest/tdeps3/d.hrl b/inttest/tdeps3/d.hrl new file mode 100644 index 0000000..02f8088 --- /dev/null +++ b/inttest/tdeps3/d.hrl @@ -0,0 +1 @@ +-include_lib("e/include/e.hrl"). diff --git a/inttest/tdeps3/d.rebar.config b/inttest/tdeps3/d.rebar.config new file mode 100644 index 0000000..4c7cd54 --- /dev/null +++ b/inttest/tdeps3/d.rebar.config @@ -0,0 +1 @@ +{deps, [{e, "1", {git, "../repo/e"}}]}. diff --git a/inttest/tdeps3/e.hrl b/inttest/tdeps3/e.hrl new file mode 100644 index 0000000..9f02fab --- /dev/null +++ b/inttest/tdeps3/e.hrl @@ -0,0 +1 @@ +-define(HELLO, hello). diff --git a/inttest/tdeps3/f.hrl b/inttest/tdeps3/f.hrl new file mode 100644 index 0000000..02f8088 --- /dev/null +++ b/inttest/tdeps3/f.hrl @@ -0,0 +1 @@ +-include_lib("e/include/e.hrl"). diff --git a/inttest/tdeps3/root.rebar.config b/inttest/tdeps3/root.rebar.config new file mode 100644 index 0000000..d1c3793 --- /dev/null +++ b/inttest/tdeps3/root.rebar.config @@ -0,0 +1 @@ +{sub_dirs, ["apps/a"]}. diff --git a/inttest/tdeps3/tdeps3_rt.erl b/inttest/tdeps3/tdeps3_rt.erl new file mode 100644 index 0000000..da87d43 --- /dev/null +++ b/inttest/tdeps3/tdeps3_rt.erl @@ -0,0 +1,89 @@ +-module(tdeps3_rt). + +-compile(export_all). + +%% Exercise transitive dependencies where there are multiple files +%% depending on the same set of deps as well as lib_dir directives +%% A -> B -> C -> D -> E +%% |--> G(via lib_dir) +%% |--> F -> D -> E + +files() -> + [ + %% A1 application + {create, "ebin/a.app", app(a, [a])}, + {template, "a.erl", "src/a.erl", dict:from_list([{module, a}, {dep, b}])}, + + {copy, "a.rebar.config", "rebar.config"}, + {copy, "../../rebar", "rebar"}, + + %% B application + {create, "repo/b/ebin/b.app", app(b, [b])}, + {template, "a.erl", "repo/b/src/b.erl", dict:from_list([{module, b}, {dep, b}])}, + {copy, "b.rebar.config", "repo/b/rebar.config"}, + {copy, "b.hrl", "repo/b/include/b.hrl"}, + + %% C application + {create, "repo/c/ebin/c.app", app(c, [c])}, + {template, "a.erl", "repo/c/src/c.erl", dict:from_list([{module, c}, {dep, d}])}, + {copy, "c.rebar.config", "repo/c/rebar.config"}, + {copy, "c.hrl", "repo/c/include/c.hrl"}, + + %% D application + {create, "repo/d/ebin/d.app", app(d, [d])}, + {template, "a.erl", "repo/d/src/d.erl", dict:from_list([{module, d}, {dep, e}])}, + {copy, "d.rebar.config", "repo/d/rebar.config"}, + {copy, "d.hrl", "repo/d/include/d.hrl"}, + + %% E application + {create, "repo/e/ebin/e.app", app(e, [])}, + {copy, "e.hrl", "repo/e/include/e.hrl"}, + + + %% F application + {create, "repo/f/ebin/f.app", app(f, [f])}, + {template, "a.erl", "repo/f/src/f.erl", dict:from_list([{module, f}, {dep, d}])}, + {copy, "c.rebar.config", "repo/f/rebar.config"}, + {copy, "f.hrl", "repo/f/include/f.hrl"}, + + %% G application, which is part of the B repo, in a lib_dir + {create, "repo/b/apps/g/ebin/g.app", app(g, [])}, + {copy, "e.hrl", "repo/b/apps/g/include/g.hrl"} + + ]. + +apply_cmds([], _Params) -> + ok; +apply_cmds([Cmd | Rest], Params) -> + io:format("Running: ~s (~p)\n", [Cmd, Params]), + {ok, _} = retest_sh:run(Cmd, Params), + apply_cmds(Rest, Params). + +run(_Dir) -> + %% Initialize the b/c apps as git repos so that dependencies pull + %% properly + GitCmds = ["git init", + "git add -A", + "git config user.email 'tdeps@example.com'", + "git config user.name 'tdeps'", + "git commit -a -m 'Initial Commit'"], + ok = apply_cmds(GitCmds, [{dir, "repo/b"}]), + ok = apply_cmds(GitCmds, [{dir, "repo/c"}]), + ok = apply_cmds(GitCmds, [{dir, "repo/d"}]), + ok = apply_cmds(GitCmds, [{dir, "repo/e"}]), + ok = apply_cmds(GitCmds, [{dir, "repo/f"}]), + + {ok, _} = retest_sh:run("./rebar -v get-deps compile", []), + ok. + +%% +%% Generate the contents of a simple .app file +%% +app(Name, Modules) -> + App = {application, Name, + [{description, atom_to_list(Name)}, + {vsn, "1"}, + {modules, Modules}, + {registered, []}, + {applications, [kernel, stdlib]}]}, + io_lib:format("~p.\n", [App]). diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 4d50f4f..6c4f5c5 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -399,18 +399,19 @@ update_code_path(Config) -> [] -> no_change; Paths -> - OldPath = code:get_path(), LibPaths = expand_lib_dirs(Paths, rebar_utils:get_cwd(), []), ok = code:add_pathsa(LibPaths), - {old, OldPath} + %% track just the paths we added, so we can remove them without + %% removing other paths added by this dep + {added, LibPaths} end. restore_code_path(no_change) -> ok; -restore_code_path({old, Path}) -> +restore_code_path({added, Paths}) -> %% Verify that all of the paths still exist -- some dynamically %% added paths can get blown away during clean. - true = code:set_path([F || F <- Path, erl_prim_loader_is_file(F)]), + [code:del_path(F) || F <- Paths, erl_prim_loader_is_file(F)], ok. erl_prim_loader_is_file(File) ->