Commits

Bob Ippolito committed ebb0e8c

wrap code:(get|set|add)_path for debugging

Comments (0)

Files changed (8)

   {modules, [ rebar,
               rebar_app_utils,
               rebar_base_compiler,
+              rebar_codepath,
               rebar_config,
               rebar_core,
               rebar_cleaner,

src/rebar_codepath.erl

+%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+%% -------------------------------------------------------------------
+%%
+%% rebar: Erlang Build Tools
+%%
+%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
+%%
+%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%% of this software and associated documentation files (the "Software"), to deal
+%% in the Software without restriction, including without limitation the rights
+%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the Software is
+%% furnished to do so, subject to the following conditions:
+%%
+%% The above copyright notice and this permission notice shall be included in
+%% all copies or substantial portions of the Software.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%% THE SOFTWARE.
+%% -------------------------------------------------------------------
+%% @doc Wrapper for code module path calls for debugging purposes.
+-module(rebar_codepath).
+-export([add_path/1, add_patha/1, add_pathsa/1, get_path/0, set_path/1]).
+-export([pretty_path/0, pretty_path/2]).
+-include("rebar.hrl").
+
+add_path(Path) ->
+    watch_path(fun () -> code:add_path(Path) end).
+
+add_patha(Path) ->
+    watch_path(fun () -> code:add_patha(Path) end).
+
+add_pathsa(Paths) ->
+    watch_path(fun () -> code:add_pathsa(Paths) end).
+
+get_path() ->
+    code:get_path().
+
+set_path(Paths) ->
+    watch_path(fun () -> code:set_path(Paths) end).
+
+watch_path(F) ->
+    OrigPath = code:get_path(),
+    Result = F(),
+    NewPath = code:get_path(),
+    case OrigPath =:= NewPath of
+        true ->
+            ok;
+        false ->
+            Orig = pretty_path(OrigPath),
+            New = pretty_path(NewPath),
+            OrigS = ordsets:from_list(Orig),
+            NewS = ordsets:from_list(New),
+            Added = ordsets:subtract(NewS, OrigS),
+            Deleted = ordsets:subtract(OrigS, NewS),
+            ?DEBUG("Code path: ~p (added: ~p, deleted: ~p)\n",
+                   [New, Added, Deleted])
+    end,
+    Result.
+
+%% @doc code:get_path(), but replace adjacent paths that begin with
+%%      code:root_dir() to the atom otp.
+pretty_path() ->
+    pretty_path(code:get_path()).
+
+pretty_path(Paths) ->
+    pretty_path(code:root_dir(), Paths).
+
+path_prefix(Path1, Path1) ->
+    true;
+path_prefix(Path1, Path2) ->
+    (lists:prefix(Path1, Path2)
+     andalso
+       (lists:prefix(Path1 ++ "/", Path2) orelse
+        lists:prefix(Path1 ++ "\\", Path2))).
+
+pretty_path(_Root, []) ->
+    [];
+pretty_path(Root, [Path | Rest]) ->
+    case path_prefix(Root, Path) of
+        true ->
+            F = fun (P) -> path_prefix(Root, P) end,
+            [otp | pretty_path(Root, lists:dropwhile(F, Rest))];
+        false ->
+            [Path | pretty_path(Root, Rest)]
+    end.

src/rebar_core.erl

         [] ->
             no_change;
         Paths ->
-            OldPath = code:get_path(),
+            OldPath = rebar_codepath:get_path(),
             LibPaths = expand_lib_dirs(Paths, rebar_utils:get_cwd(), []),
-            ok = code:add_pathsa(LibPaths),
+            ok = rebar_codepath:add_pathsa(LibPaths),
             {old, OldPath}
     end.
 
 restore_code_path({old, Path}) ->
     %% Verify that all of the paths still exist -- some dynamically add paths
     %% can get blown away during clean.
-    true = code:set_path(lists:filter(fun filelib:is_file/1, Path)),
+    true = rebar_codepath:set_path(lists:filter(fun filelib:is_file/1, Path)),
     ok.
 
 

src/rebar_deps.erl

 update_deps_code_path([Dep | Rest]) ->
     case is_app_available(Dep#dep.app, Dep#dep.vsn_regex, Dep#dep.dir) of
         {true, _} ->
-            code:add_patha(filename:join(Dep#dep.dir, ebin));
+            rebar_codepath:add_patha(filename:join(Dep#dep.dir, ebin));
         false ->
             ok
     end,
                 {true, _} ->
                     %% Available version matches up -- we're good to go; add the
                     %% app dir to our code path
-                    code:add_patha(filename:join(Dep#dep.dir, ebin)),
+                    rebar_codepath:add_patha(filename:join(Dep#dep.dir, ebin)),
                     Dep;
                 false ->
                     %% The app that was downloaded doesn't match up (or had

src/rebar_erlc_compiler.erl

 
     %% Make sure that ebin/ exists and is on the path
     ok = filelib:ensure_dir(filename:join("ebin", "dummy.beam")),
-    CurrPath = code:get_path(),
-    code:add_path("ebin"),
+    CurrPath = rebar_codepath:get_path(),
+    rebar_codepath:add_path("ebin"),
     rebar_base_compiler:run(Config, FirstErls, SortedRestErls,
                             fun(S, C) -> internal_erl_compile(S, C, OutDir,
                                                               ErlOpts)
                             end),
-    code:set_path(CurrPath),
+    rebar_codepath:set_path(CurrPath),
     ok.
 
 

src/rebar_eunit.erl

 set_proc_env() ->
     %% Save current code path and then prefix ?EUNIT_DIR on it so that our modules
     %% are found there
-    CodePath = code:get_path(),
-    true = code:add_patha(eunit_dir()),
+    CodePath = rebar_codepath:get_path(),
+    true = rebar_codepath:add_patha(eunit_dir()),
 
     %% Move down into ?EUNIT_DIR while we run tests so any generated files
     %% are created there (versus in the source dir)
     %% Return to original working dir
     file:set_cwd(Cwd),
     %% Restore code path
-    true = code:set_path(CodePath).
+    true = rebar_codepath:set_path(CodePath).
 
 get_eunit_opts(Config) ->
     %% Enable verbose in eunit if so requested..

src/rebar_otp_app.erl

             ok = file:write_file(AppFile, Spec),
 
             %% Make certain that the ebin/ directory is available on the code path
-            code:add_path(filename:absname(filename:dirname(AppFile))),
+            rebar_codepath:add_path(filename:absname(filename:dirname(AppFile))),
 
             AppFile;
 

src/rebar_xref.erl

     {ok, _} = xref:add_directory(xref, "ebin"),
 
     %% Save the code path prior to doing anything
-    OrigPath = code:get_path(),
-    code:add_path(filename:join(rebar_utils:get_cwd(), "ebin")),
+    OrigPath = rebar_codepath:get_path(),
+    rebar_codepath:add_path(filename:join(rebar_utils:get_cwd(), "ebin")),
 
     %% Get list of xref checks we want to run
     XrefChecks = rebar_config:get(Config, xref_checks, [exports_not_used,
     end,
 
     %% Restore the original code path
-    code:set_path(OrigPath),
+    rebar_codepath:set_path(OrigPath),
 
     ok.
 
 
 
 code_path() ->
-    [P || P <- code:get_path(),
+    [P || P <- rebar_codepath:get_path(),
           filelib:is_dir(P)] ++ [filename:join(rebar_utils:get_cwd(), "ebin")].
 
 %%