diff options
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | inttest/depplugins/depplugins_rt.erl | 50 | ||||
-rw-r--r-- | inttest/depplugins/rebar.config | 1 | ||||
-rw-r--r-- | inttest/depplugins/rebar_dependsonplugin.config | 2 | ||||
-rw-r--r-- | inttest/depplugins/testplugin_mod.erl | 6 | ||||
-rw-r--r-- | inttest/tdeps1/tdeps1_rt.erl | 17 | ||||
-rw-r--r-- | inttest/tdeps2/tdeps2_rt.erl | 19 | ||||
-rwxr-xr-x | priv/templates/simplenode.nodetool | 2 | ||||
-rw-r--r-- | priv/templates/simplenode.reltool.config | 6 | ||||
-rw-r--r-- | priv/templates/simplenode.windows.runner.cmd | 9 | ||||
-rw-r--r-- | src/rebar_base_compiler.erl | 2 | ||||
-rw-r--r-- | src/rebar_core.erl | 40 | ||||
-rw-r--r-- | src/rebar_ct.erl | 26 | ||||
-rw-r--r-- | src/rebar_port_compiler.erl | 3 |
15 files changed, 152 insertions, 36 deletions
diff --git a/.travis.yml b/.travis.yml index c01e70c..191d337 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: erlang otp_release: + - R16B - R15B01 - R15B - R14B04 @@ -24,7 +24,7 @@ dialyzer: dialyzer_warnings @diff -U0 dialyzer_reference dialyzer_warnings dialyzer_warnings: - -@dialyzer -q -n ebin -Wunmatched_returns -Werror_handling \ + -@dialyzer -q -nn -n ebin -Wunmatched_returns -Werror_handling \ -Wrace_conditions > dialyzer_warnings binary: VSN = $(shell ./rebar -V) @@ -38,6 +38,6 @@ deps: test: @$(REBAR) eunit - @$(RETEST) inttest + @$(RETEST) -v inttest travis: clean debug xref clean all deps test diff --git a/inttest/depplugins/depplugins_rt.erl b/inttest/depplugins/depplugins_rt.erl new file mode 100644 index 0000000..7b106eb --- /dev/null +++ b/inttest/depplugins/depplugins_rt.erl @@ -0,0 +1,50 @@ +%%% @doc Plugin handling test +%%% +%%% This test checks if plugins are loaded correctly. +%%% +%%% It has three applications: +%%% <ol> +%%% <li>fish. top-level module, has one dependency: `dependsonplugin'.</li> +%%% <li>dependsonplugin. This depends on some pre-compile actions by the +%%% plugin. In the test the plugin creates a file `pre.compile' in the +%%% top-level folder of this application.</li> +%%% <li>testplugin. This is a plugin application which creates the file.</li> +%%% </ol> + +-module(depplugins_rt). +-compile(export_all). + +-include_lib("eunit/include/eunit.hrl"). + +files() -> + [ + {copy, "../../rebar", "rebar"}, + {copy, "rebar.config", "rebar.config"}, + {create, "ebin/fish.app", app(fish, [])}, + + {create, "deps/dependsonplugin/ebin/dependsonplugin.app", + app(dependsonplugin, [])}, + {copy, "rebar_dependsonplugin.config", + "deps/dependsonplugin/rebar.config"}, + {copy, "testplugin_mod.erl", + "deps/testplugin/plugins/testplugin_mod.erl"}, + {create, "deps/testplugin/ebin/testplugin.app", + app(testplugin, [])} + ]. + +run(_Dir) -> + ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])), + ?assertEqual(true, filelib:is_regular("deps/dependsonplugin/pre.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/inttest/depplugins/rebar.config b/inttest/depplugins/rebar.config new file mode 100644 index 0000000..3a2e34e --- /dev/null +++ b/inttest/depplugins/rebar.config @@ -0,0 +1 @@ +{deps, [dependsonplugin]}. diff --git a/inttest/depplugins/rebar_dependsonplugin.config b/inttest/depplugins/rebar_dependsonplugin.config new file mode 100644 index 0000000..df36213 --- /dev/null +++ b/inttest/depplugins/rebar_dependsonplugin.config @@ -0,0 +1,2 @@ +{deps, [testplugin]}. +{plugins, [testplugin_mod]}. diff --git a/inttest/depplugins/testplugin_mod.erl b/inttest/depplugins/testplugin_mod.erl new file mode 100644 index 0000000..055bbc7 --- /dev/null +++ b/inttest/depplugins/testplugin_mod.erl @@ -0,0 +1,6 @@ +-module(testplugin_mod). +-compile(export_all). + +pre_compile(Config, _) -> + ok = file:write_file("pre.compile", <<"Yadda!">>), + rebar_log:log(info, "Wrote ~p/pre.compile~n", [rebar_utils:get_cwd()]). diff --git a/inttest/tdeps1/tdeps1_rt.erl b/inttest/tdeps1/tdeps1_rt.erl index 9f21c81..3de1a2b 100644 --- a/inttest/tdeps1/tdeps1_rt.erl +++ b/inttest/tdeps1/tdeps1_rt.erl @@ -23,12 +23,23 @@ files() -> {copy, "c.hrl", "repo/c/include/c.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 - GitCmd = "/bin/sh -c \"git init && git add -A && git commit -a -m 'Initial commit'\"", - {ok, _} = retest_sh:run(GitCmd, [{dir, "repo/b"}]), - {ok, _} = retest_sh:run(GitCmd, [{dir, "repo/c"}]), + GitCmds = ["git init", + "git add -A", + "git config user.email 'tdeps@example.com'", + "git config user.name 'tdeps'", + "git commit -a -m 'Initial Commit'"], + apply_cmds(GitCmds, [{dir, "repo/b"}]), + apply_cmds(GitCmds, [{dir, "repo/c"}]), {ok, _} = retest_sh:run("./rebar get-deps compile", []), diff --git a/inttest/tdeps2/tdeps2_rt.erl b/inttest/tdeps2/tdeps2_rt.erl index dca5f03..987567e 100644 --- a/inttest/tdeps2/tdeps2_rt.erl +++ b/inttest/tdeps2/tdeps2_rt.erl @@ -31,12 +31,23 @@ files() -> {copy, "c.hrl", "repo/c/include/c.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 mercurial repos so that dependencies pull + %% Initialize the b/c apps as git repos so that dependencies pull %% properly - GitCmd = "/bin/sh -c \"git init && git add -A && git commit -a -m 'Initial commit'\"", - {ok, _} = retest_sh:run(GitCmd, [{dir, "repo/b"}]), - {ok, _} = retest_sh:run(GitCmd, [{dir, "repo/c"}]), + 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, _} = retest_sh:run("./rebar -v get-deps compile", []), ok. diff --git a/priv/templates/simplenode.nodetool b/priv/templates/simplenode.nodetool index 54ee6d6..ce06c6a 100755 --- a/priv/templates/simplenode.nodetool +++ b/priv/templates/simplenode.nodetool @@ -6,8 +6,6 @@ %% nodetool: Helper Script for interacting with live nodes %% %% ------------------------------------------------------------------- --mode(compile). - main(Args) -> ok = start_epmd(), %% Extract the args diff --git a/priv/templates/simplenode.reltool.config b/priv/templates/simplenode.reltool.config index 4189329..bac7270 100644 --- a/priv/templates/simplenode.reltool.config +++ b/priv/templates/simplenode.reltool.config @@ -19,9 +19,9 @@ {boot_rel, "{{nodeid}}"}, {profile, embedded}, {incl_cond, derived}, - {mod_cond, derived}, {excl_archive_filters, [".*"]}, %% Do not archive built libs - {excl_sys_filters, ["^bin/.*", "^erts.*/bin/(dialyzer|typer)", + {excl_sys_filters, ["^bin/(?!start_clean.boot)", + "^erts.*/bin/(dialyzer|typer)", "^erts.*/(doc|info|include|lib|man|src)"]}, {excl_app_filters, ["\.gitignore"]}, {app, {{nodeid}}, [{mod_cond, app}, {incl_cond, include}]} @@ -33,6 +33,8 @@ {mkdir, "log/sasl"}, {copy, "files/erl", "\{\{erts_vsn\}\}/bin/erl"}, {copy, "files/nodetool", "\{\{erts_vsn\}\}/bin/nodetool"}, + {copy, "{{nodeid}}/bin/start_clean.boot", + "\{\{erts_vsn\}\}/bin/start_clean.boot"}, {copy, "files/{{nodeid}}", "bin/{{nodeid}}"}, {copy, "files/{{nodeid}}.cmd", "bin/{{nodeid}}.cmd"}, {copy, "files/start_erl.cmd", "bin/start_erl.cmd"}, diff --git a/priv/templates/simplenode.windows.runner.cmd b/priv/templates/simplenode.windows.runner.cmd index 16da5b9..d45f438 100644 --- a/priv/templates/simplenode.windows.runner.cmd +++ b/priv/templates/simplenode.windows.runner.cmd @@ -30,6 +30,7 @@ @set epmd="%erts_bin%\epmd.exe" @set escript="%erts_bin%\escript.exe" @set werl="%erts_bin%\werl.exe" +@set nodetool="%erts_bin%\nodetool" @if "%1"=="usage" @goto usage @if "%1"=="install" @goto install @@ -38,13 +39,14 @@ @if "%1"=="stop" @goto stop @if "%1"=="restart" @call :stop && @goto start @if "%1"=="console" @goto console +@if "%1"=="ping" @goto ping @if "%1"=="query" @goto query @if "%1"=="attach" @goto attach @if "%1"=="upgrade" @goto upgrade @echo Unknown command: "%1" :usage -@echo Usage: %~n0 [install^|uninstall^|start^|stop^|restart^|console^|query^|attach^|upgrade] +@echo Usage: %~n0 [install^|uninstall^|start^|stop^|restart^|console^|ping^|query^|attach^|upgrade] @goto :EOF :install @@ -71,6 +73,11 @@ @start "%node_name% console" %werl% -boot "%node_boot_script%" -config "%sys_config%" -args_file "%vm_args%" -sname %node_name% @goto :EOF +:ping +@%escript% %nodetool% ping -sname "%node_name%" -setcookie "%erlang_cookie%" +@exit %ERRORLEVEL% +@goto :EOF + :query @%erlsrv% list %service_name% @exit %ERRORLEVEL% diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index 260cdaf..a0dec30 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -226,6 +226,8 @@ format_warnings(Config, Source, Warnings, Opts) -> maybe_report([{error, {error, _Es, _Ws}=ErrorsAndWarnings}, {source, _}]) -> maybe_report(ErrorsAndWarnings); +maybe_report([{error, E}, {source, S}]) -> + report(["unexpected error compiling " ++ S, io_lib:fwrite("~n~p~n", [E])]); maybe_report({error, Es, Ws}) -> report(Es), report(Ws); diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 36923a5..3172d64 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -530,35 +530,41 @@ plugin_modules(Config, PredirsAssoc, FoundModules, MissingModules) -> load_plugin_modules(Config, PredirsAssoc, Modules) -> Cwd = rebar_utils:get_cwd(), - PluginDir = case rebar_config:get_local(Config, plugin_dir, undefined) of - undefined -> - filename:join(Cwd, "plugins"); - Dir -> - Dir - end, + PluginDirs = case rebar_config:get_local(Config, plugin_dir, undefined) of + undefined -> + % Plugin can be in the project's "plugins" folder + [filename:join(Cwd, "plugins")]; + Dir -> + [Dir] + end ++ + % We also want to include this case: + % Plugin can be in "plugins" directory of the plugin base directory. For + % example, Cwd depends on Plugin, and deps/Plugin/plugins/Plugin.erl is the + % plugin. + [ + filename:join(Dir, "plugins") || + Dir <- get_plugin_base_dirs(Cwd, PredirsAssoc) + ], %% Find relevant sources in base_dir and plugin_dir Erls = string:join([atom_to_list(M)++"\\.erl" || M <- Modules], "|"), RE = "^" ++ Erls ++ "\$", - BaseDir = get_plugin_base_dir(Cwd, PredirsAssoc), %% If a plugin is found both in base_dir and plugin_dir, the clash %% will provoke an error and we'll abort. - Sources = rebar_utils:find_files(PluginDir, RE, false) - ++ rebar_utils:find_files(BaseDir, RE, false), + Sources = [rebar_utils:find_files(PD, RE, false) || PD <- PluginDirs], %% Compile and load plugins - Loaded = [load_plugin(Src) || Src <- Sources], + Loaded = [load_plugin(Src) || Src <- lists:append(Sources)], FilterMissing = is_missing_plugin(Loaded), NotLoaded = [V || V <- Modules, FilterMissing(V)], {Loaded, NotLoaded}. -get_plugin_base_dir(Cwd, PredirsAssoc) -> - case dict:find(Cwd, PredirsAssoc) of - {ok, BaseDir} -> - BaseDir; - error -> - Cwd - end. +%% @doc PredirsAssoc is a dictionary of plugindir -> 'parent' pairs +%% 'parent' in this case depends on plugin; therefore we have to give +%% all plugins that Cwd ('parent' in this case) depends on. +get_plugin_base_dirs(Cwd, PredirsAssoc) -> + [PluginDir || {PluginDir, Master} <- dict:to_list(PredirsAssoc), + Master =:= Cwd]. is_missing_plugin(Loaded) -> fun(Mod) -> not lists:member(Mod, Loaded) end. diff --git a/src/rebar_ct.erl b/src/rebar_ct.erl index d5b1d26..9951f8e 100644 --- a/src/rebar_ct.erl +++ b/src/rebar_ct.erl @@ -108,8 +108,16 @@ run_test(TestDir, LogDir, Config, _File) -> " 2>&1 | tee -a " ++ RawLog end, - rebar_utils:sh(Cmd ++ Output, [{env,[{"TESTDIR", TestDir}]}]), - check_log(Config, RawLog). + case rebar_utils:sh(Cmd ++ Output, [{env,[{"TESTDIR", TestDir}]}, return_on_error]) of + {ok,_} -> + %% in older versions of ct_run, this could have been a failure + %% that returned a non-0 code. Check for that! + check_success_log(Config, RawLog); + {error,Res} -> + %% In newer ct_run versions, this may be a sign of a good compile + %% that failed cases. In older version, it's a worse error. + check_fail_log(Config, RawLog, Cmd ++ Output, Res) + end. clear_log(LogDir, RawLog) -> case filelib:ensure_dir(filename:join(LogDir, "index.html")) of @@ -124,7 +132,16 @@ clear_log(LogDir, RawLog) -> %% calling ct with erl does not return non-zero on failure - have to check %% log results -check_log(Config, RawLog) -> +check_success_log(Config, RawLog) -> + check_log(Config, RawLog, fun(Msg) -> ?CONSOLE("DONE.\n~s\n", [Msg]) end). + +check_fail_log(Config, RawLog, Command, {Rc, Output}) -> + check_log(Config, RawLog, fun(_Msg) -> + ?ABORT("~s failed with error: ~w and output:~n~s~n", + [Command, Rc, Output]) + end). + +check_log(Config,RawLog,Fun) -> {ok, Msg} = rebar_utils:sh("grep -e 'TEST COMPLETE' -e '{error,make_failed}' " ++ RawLog, [{use_stdout, false}]), @@ -142,9 +159,10 @@ check_log(Config, RawLog) -> ?FAIL; true -> - ?CONSOLE("DONE.\n~s\n", [Msg]) + Fun(Msg) end. + %% Show the log if it hasn't already been shown because verbose was on show_log(Config, RawLog) -> ?CONSOLE("Showing log\n", []), diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl index 36d741d..0abb044 100644 --- a/src/rebar_port_compiler.erl +++ b/src/rebar_port_compiler.erl @@ -100,7 +100,8 @@ compile(Config, AppFile) -> [] -> ok; Specs -> - SharedEnv = rebar_config:get_env(Config, ?MODULE), + SharedEnv = rebar_config:get_env(Config, rebar_deps) ++ + rebar_config:get_env(Config, ?MODULE), %% Compile each of the sources NewBins = compile_sources(Config, Specs, SharedEnv), |