diff options
-rw-r--r-- | CONTRIBUTING.md | 4 | ||||
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | priv/templates/app.erl | 3 | ||||
-rw-r--r-- | src/rebar3.erl | 21 | ||||
-rw-r--r-- | src/rebar_prv_common_test.erl | 20 | ||||
-rw-r--r-- | src/rebar_prv_dialyzer.erl | 2 | ||||
-rw-r--r-- | src/rebar_prv_eunit.erl | 20 | ||||
-rw-r--r-- | src/rebar_prv_packages.erl | 32 | ||||
-rw-r--r-- | src/rebar_prv_path.erl | 8 | ||||
-rw-r--r-- | src/rebar_prv_report.erl | 2 | ||||
-rw-r--r-- | src/rebar_prv_shell.erl | 18 | ||||
-rw-r--r-- | test/rebar_ct_SUITE.erl | 32 | ||||
-rw-r--r-- | test/rebar_eunit_SUITE.erl | 43 | ||||
-rw-r--r-- | test/rebar_profiles_SUITE.erl | 14 |
14 files changed, 170 insertions, 59 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f175cc2..8077813 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ All files without specific headers can safely be assumed to be under Apache ## Submitting a Bug -Bugs can be submitted to the [Github issue page](https://github.com/rebar/rebar3/issues). +Bugs can be submitted to the [Github issue page](https://github.com/erlang/rebar3/issues). Rebar3 is not perfect software and will be buggy. When submitting a bug, be careful to know the following: @@ -58,7 +58,7 @@ Before requesting or implementing a new feature, please do the following: - Take a look at our [list of plugins](http://www.rebar3.org/docs/using-available-plugins) to know if the feature isn't already supported by the community. -- Verify in existing [tickets](https://github.com/rebar/rebar3/issues) whether +- Verify in existing [tickets](https://github.com/erlang/rebar3/issues) whether the feature might already is in the works, has been moved to a plugin, or has already been rejected. @@ -1,6 +1,6 @@ # Rebar3 -[![Build Status](https://travis-ci.org/rebar/rebar3.svg?branch=master)](https://travis-ci.org/rebar/rebar3) [![Windows build status](https://ci.appveyor.com/api/projects/status/yx4oitd9pvd2kab3?svg=true)](https://ci.appveyor.com/project/TristanSloughter/rebar3) +[![Build Status](https://travis-ci.org/erlang/rebar3.svg?branch=master)](https://travis-ci.org/erlang/rebar3) [![Windows build status](https://ci.appveyor.com/api/projects/status/yx4oitd9pvd2kab3?svg=true)](https://ci.appveyor.com/project/TristanSloughter/rebar3) 1. [What is Rebar3?](#what-is-rebar3) 2. [Why Rebar3?](#why-rebar3) @@ -64,12 +64,12 @@ $ wget https://s3.amazonaws.com/rebar3/rebar3 && chmod +x rebar3 From Source (assuming you have a full Erlang install): ```bash -$ git clone https://github.com/rebar/rebar3.git +$ git clone https://github.com/erlang/rebar3.git $ cd rebar3 $ ./bootstrap ``` -Stable versions can be obtained from the [releases page](https://github.com/rebar/rebar3/releases). +Stable versions can be obtained from the [releases page](https://github.com/erlang/rebar3/releases). The rebar3 escript can also extract itself with a run script under the user's home directory: @@ -159,13 +159,13 @@ quick feedback, you can try the #rebar channel on asking about things with well known answers. For bug reports, roadmaps, and issues, visit the [github issues -page](https://github.com/rebar/rebar3/issues). +page](https://github.com/erlang/rebar3/issues). General rebar community resources and links: - [Rebar Mailing List](http://lists.basho.com/pipermail/rebar_lists.basho.com/) - #rebar on [irc.freenode.net](http://freenode.net/) -- [issues](https://github.com/rebar/rebar3/issues) +- [issues](https://github.com/erlang/rebar3/issues) - [Documentation](http://www.rebar3.org/v3.0/docs) To contribute to rebar3, please refer to [CONTRIBUTING](CONTRIBUTING.md). diff --git a/priv/templates/app.erl b/priv/templates/app.erl index 83eb9a3..62d2ddf 100644 --- a/priv/templates/app.erl +++ b/priv/templates/app.erl @@ -8,8 +8,7 @@ -behaviour(application). %% Application callbacks --export([start/2 - ,stop/1]). +-export([start/2, stop/1]). %%==================================================================== %% API diff --git a/src/rebar3.erl b/src/rebar3.erl index ab7d35a..c1a1ae4 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -337,19 +337,18 @@ state_from_global_config(Config, GlobalConfigFile) -> test_state(State) -> ErlOpts = rebar_state:get(State, erl_opts, []), - TestOpts = safe_define_test_macro(ErlOpts, 'TEST'), - MoreTestOpts = safe_define_test_macro(ErlOpts, 'EUNIT'), - [{extra_src_dirs, ["test"]}, {erl_opts, TestOpts ++ MoreTestOpts}]. + TestOpts = safe_define_test_macro(ErlOpts), + [{extra_src_dirs, ["test"]}, {erl_opts, TestOpts}]. -safe_define_test_macro(Opts, Macro) -> +safe_define_test_macro(Opts) -> %% defining a compile macro twice results in an exception so - %% make sure 'TEST' or 'EUNIT' is only defined once - case test_defined(Opts, Macro) of + %% make sure 'TEST' is only defined once + case test_defined(Opts) of true -> []; - false -> [{d, Macro}] + false -> [{d, 'TEST'}] end. -test_defined([{d, Macro}|_], Macro) -> true; -test_defined([{d, Macro, true}|_], Macro) -> true; -test_defined([_|Rest], Macro) -> test_defined(Rest, Macro); -test_defined([], _) -> false. +test_defined([{d, 'TEST'}|_]) -> true; +test_defined([{d, 'TEST', true}|_]) -> true; +test_defined([_|Rest]) -> test_defined(Rest); +test_defined([]) -> false. diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index 784b682..6b94f79 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -329,9 +329,27 @@ include_files(Opts, Tests) -> Is = lists:map(fun(I) -> {i, I} end, Includes), case append(Is, ErlOpts) of {error, _} = Error -> Error; - NewIncludes -> rebar_opts:set(Opts, erl_opts, NewIncludes) + NewIncludes -> ct_macro(rebar_opts:set(Opts, erl_opts, NewIncludes)) end. +ct_macro(Opts) -> + ErlOpts = opts(Opts, erl_opts, []), + NewOpts = safe_define_ct_macro(ErlOpts), + rebar_opts:set(Opts, erl_opts, NewOpts). + +safe_define_ct_macro(Opts) -> + %% defining a compile macro twice results in an exception so + %% make sure 'COMMON_TEST' is only defined once + case test_defined(Opts) of + true -> Opts; + false -> [{d, 'COMMON_TEST'}|Opts] + end. + +test_defined([{d, 'COMMON_TEST'}|_]) -> true; +test_defined([{d, 'COMMON_TEST', true}|_]) -> true; +test_defined([_|Rest]) -> test_defined(Rest); +test_defined([]) -> false. + append({error, _} = Error, _) -> Error; append(_, {error, _} = Error) -> Error; append(A, B) -> A ++ B. diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index 834eb98..622ee60 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/src/rebar_prv_dialyzer.erl @@ -97,7 +97,7 @@ do(State) -> end. %% This is used to workaround dialyzer quirk discussed here -%% https://github.com/rebar/rebar3/pull/489#issuecomment-107953541 +%% https://github.com/erlang/rebar3/pull/489#issuecomment-107953541 %% Dialyzer gets default plt location wrong way by peeking HOME environment %% variable which usually is not defined on Windows. maybe_fix_env() -> diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index c085ee4..46ea48d 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -244,9 +244,27 @@ first_files(Opts) -> EUnitFirstFiles = opts(Opts, eunit_first_files, []), case append(EUnitFirstFiles, FirstFiles) of {error, _} = Error -> Error; - NewFirstFiles -> rebar_opts:set(Opts, erl_first_files, NewFirstFiles) + NewFirstFiles -> eunit_macro(rebar_opts:set(Opts, erl_first_files, NewFirstFiles)) end. +eunit_macro(Opts) -> + ErlOpts = opts(Opts, erl_opts, []), + NewOpts = safe_define_eunit_macro(ErlOpts), + rebar_opts:set(Opts, erl_opts, NewOpts). + +safe_define_eunit_macro(Opts) -> + %% defining a compile macro twice results in an exception so + %% make sure 'EUNIT' is only defined once + case test_defined(Opts) of + true -> Opts; + false -> [{d, 'EUNIT'}|Opts] + end. + +test_defined([{d, 'EUNIT'}|_]) -> true; +test_defined([{d, 'EUNIT', true}|_]) -> true; +test_defined([_|Rest]) -> test_defined(Rest); +test_defined([]) -> false. + append({error, _} = Error, _) -> Error; append(_, {error, _} = Error) -> Error; append(A, B) -> A ++ B. diff --git a/src/rebar_prv_packages.erl b/src/rebar_prv_packages.erl index 998320c..7217ab8 100644 --- a/src/rebar_prv_packages.erl +++ b/src/rebar_prv_packages.erl @@ -28,22 +28,19 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> rebar_packages:packages(State), - print_packages(), + case rebar_state:command_args(State) of + [Name] -> + print_packages(get_packages(iolist_to_binary(Name))); + _ -> + print_packages(sort_packages()) + end, {ok, State}. -spec format_error(any()) -> iolist(). format_error(load_registry_fail) -> "Failed to load package regsitry. Try running 'rebar3 update' to fix". -print_packages() -> - SortedPkgs = ets:foldl(fun({package_index_version, _}, Acc) -> - Acc; - ({Pkg, Vsns}, Acc) -> - orddict:store(Pkg, Vsns, Acc); - (_, Acc) -> - Acc - end, orddict:new(), ?PACKAGE_TABLE), - +print_packages(Pkgs) -> orddict:map(fun(Name, Vsns) -> SortedVsns = lists:sort(fun(A, B) -> ec_semver:lte(ec_semver:parse(A) @@ -51,7 +48,20 @@ print_packages() -> end, Vsns), VsnStr = join(SortedVsns, <<", ">>), ?CONSOLE("~s:~n Versions: ~s~n", [Name, VsnStr]) - end, SortedPkgs). + end, Pkgs). + +sort_packages() -> + ets:foldl(fun({package_index_version, _}, Acc) -> + Acc; + ({Pkg, Vsns}, Acc) -> + orddict:store(Pkg, Vsns, Acc); + (_, Acc) -> + Acc + end, orddict:new(), ?PACKAGE_TABLE). + +get_packages(Name) -> + ets:lookup(?PACKAGE_TABLE, Name). + -spec join([binary()], binary()) -> binary(). join([Bin], _Sep) -> diff --git a/src/rebar_prv_path.erl b/src/rebar_prv_path.erl index 37c9834..4e88496 100644 --- a/src/rebar_prv_path.erl +++ b/src/rebar_prv_path.erl @@ -95,10 +95,14 @@ print_paths_if_exist(Paths, State) -> project_deps(State) -> Profiles = rebar_state:current_profiles(State), - List = lists:foldl(fun(Profile, Acc) -> rebar_state:get(State, {deps, Profile}, []) ++ Acc end, [], Profiles), - Deps = [normalize(Name) || {Name, _} <- List], + DepList = lists:foldl(fun(Profile, Acc) -> rebar_state:get(State, {deps, Profile}, []) ++ Acc end, [], Profiles), + LockList = lists:foldl(fun(Profile, Acc) -> rebar_state:get(State, {locks, Profile}, []) ++ Acc end, [], Profiles), + Deps = [normalize(name(Dep)) || Dep <- DepList++LockList], lists:usort(Deps). +name(App) when is_tuple(App) -> element(1, App); +name(Name) when is_binary(Name); is_list(Name); is_atom(Name) -> Name. + normalize(AppName) when is_list(AppName) -> AppName; normalize(AppName) when is_atom(AppName) -> atom_to_list(AppName); normalize(AppName) when is_binary(AppName) -> binary_to_list(AppName). diff --git a/src/rebar_prv_report.erl b/src/rebar_prv_report.erl index 587fad7..d6c8b60 100644 --- a/src/rebar_prv_report.erl +++ b/src/rebar_prv_report.erl @@ -13,7 +13,7 @@ -define(PROVIDER, report). -define(DEPS, []). --define(ISSUES_URL, "https://github.com/rebar/rebar3/issues"). +-define(ISSUES_URL, "https://github.com/erlang/rebar3/issues"). %% =================================================================== %% Public API diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl index 430d1e8..d67f940 100644 --- a/src/rebar_prv_shell.erl +++ b/src/rebar_prv_shell.erl @@ -133,11 +133,25 @@ kill_old_user() -> %% fully die [P] = [P || P <- element(2,process_info(whereis(user), links)), is_port(P)], user ! {'EXIT', P, normal}, % pretend the port died, then the port can die! + exit(P, kill), + wait_for_port_death(1000, P), OldUser. +wait_for_port_death(N, _) when N < 0 -> + %% This risks displaying a warning! + whatever; +wait_for_port_death(N, P) -> + case erlang:port_info(P) of + undefined -> + ok; + _ -> + timer:sleep(10), + wait_for_port_death(N-10, P) + end. + setup_new_shell() -> - %% terminate the current user supervision structure - ok = supervisor:terminate_child(kernel_sup, user), + %% terminate the current user supervision structure, if any + _ = supervisor:terminate_child(kernel_sup, user), %% start a new shell (this also starts a new user under the correct group) _ = user_drv:start(), %% wait until user_drv and user have been registered (max 3 seconds) diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 0e0de2e..1da7571 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -6,8 +6,10 @@ end_per_group/2]). -export([basic_app_default_dirs/1, basic_app_default_beams/1, + basic_app_ct_macro/1, multi_app_default_dirs/1, multi_app_default_beams/1, + multi_app_ct_macro/1, single_app_dir/1, single_extra_dir/1, single_unmanaged_dir/1, @@ -65,9 +67,11 @@ all() -> [{group, basic_app}, misspecified_ct_first_files]. groups() -> [{basic_app, [], [basic_app_default_dirs, - basic_app_default_beams]}, + basic_app_default_beams, + basic_app_ct_macro]}, {multi_app, [], [multi_app_default_dirs, - multi_app_default_beams]}, + multi_app_default_beams, + multi_app_ct_macro]}, {dirs_and_suites, [], [single_app_dir, single_extra_dir, single_unmanaged_dir, @@ -121,7 +125,7 @@ init_per_group(basic_app, Config) -> {ok, T} = Tests, Opts = rebar_prv_common_test:translate_paths(NewState, T), - [{result, Opts}, {appnames, [Name]}|C]; + [{result, Opts}, {appnames, [Name]}, {compile_state, NewState}|C]; init_per_group(multi_app, Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_"), @@ -156,7 +160,7 @@ init_per_group(multi_app, Config) -> {ok, T} = Tests, Opts = rebar_prv_common_test:translate_paths(NewState, T), - [{result, Opts}, {appnames, [Name1, Name2]}|C]; + [{result, Opts}, {appnames, [Name1, Name2]}, {compile_state, NewState}|C]; init_per_group(dirs_and_suites, Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_"), @@ -255,6 +259,15 @@ basic_app_default_beams(Config) -> true = filelib:is_file(File). +basic_app_ct_macro(Config) -> + State = ?config(compile_state, Config), + + [App] = rebar_state:project_apps(State), + Opts = rebar_app_info:opts(App), + ErlOpts = dict:fetch(erl_opts, Opts), + true = lists:member({d, 'COMMON_TEST'}, ErlOpts). + + multi_app_default_dirs(Config) -> AppDir = ?config(apps, Config), [Name1, Name2] = ?config(appnames, Config), @@ -296,6 +309,16 @@ multi_app_default_beams(Config) -> true = filelib:is_file(File2), true = filelib:is_file(File3). +multi_app_ct_macro(Config) -> + State = ?config(compile_state, Config), + + Apps = rebar_state:project_apps(State), + lists:foreach(fun(App) -> + Opts = rebar_app_info:opts(App), + ErlOpts = dict:fetch(erl_opts, Opts), + true = lists:member({d, 'COMMON_TEST'}, ErlOpts) + end, Apps). + single_app_dir(Config) -> AppDir = ?config(apps, Config), [Name1, _Name2] = ?config(appnames, Config), @@ -1158,6 +1181,7 @@ misspecified_ct_first_files(Config) -> {badconfig, {"Value `~p' of option `~p' must be a list", {some_file, ct_first_files}}} = Error. + %% helper for generating test data test_suite(Name) -> io_lib:format("-module(~ts_SUITE).\n" diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index cb2c911..41ab6ff 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -2,8 +2,12 @@ -export([all/0, groups/0]). -export([init_per_suite/1, init_per_group/2, end_per_group/2]). --export([basic_app_compiles/1, basic_app_files/1, basic_app_exports/1, basic_app_testset/1]). --export([multi_app_compiles/1, multi_app_files/1, multi_app_exports/1, multi_app_testset/1]). +-export([basic_app_compiles/1, basic_app_files/1]). +-export([basic_app_exports/1, basic_app_testset/1]). +-export([basic_app_eunit_macro/1]). +-export([multi_app_compiles/1, multi_app_files/1]). +-export([multi_app_exports/1, multi_app_testset/1]). +-export([multi_app_eunit_macro/1]). -export([eunit_tests/1, eunit_opts/1, eunit_first_files/1]). -export([single_application_arg/1, multi_application_arg/1, missing_application_arg/1]). -export([single_module_arg/1, multi_module_arg/1, missing_module_arg/1]). @@ -27,9 +31,15 @@ all() -> groups() -> [{basic_app, [sequence], [basic_app_compiles, {group, basic_app_results}]}, - {basic_app_results, [], [basic_app_files, basic_app_exports, basic_app_testset]}, + {basic_app_results, [], [basic_app_files, + basic_app_exports, + basic_app_testset, + basic_app_eunit_macro]}, {multi_app, [sequence], [multi_app_compiles, {group, multi_app_results}]}, - {multi_app_results, [], [multi_app_files, multi_app_exports, multi_app_testset]}, + {multi_app_results, [], [multi_app_files, + multi_app_exports, + multi_app_testset, + multi_app_eunit_macro]}, {cmd_line_args, [], [eunit_tests, eunit_opts, eunit_first_files, single_application_arg, multi_application_arg, missing_application_arg, single_module_arg, multi_module_arg, missing_module_arg, @@ -160,7 +170,16 @@ basic_app_testset(Config) -> {module, basic_app_tests_helper}]}, Set = rebar_prv_eunit:prepare_tests(Result). - +basic_app_eunit_macro(_Config) -> + Macro = fun(Mod) -> + begin + Path = code:which(Mod), + {ok, {Mod, [{compile_info, CompileInfo}]}} = beam_lib:chunks(Path, [compile_info]), + Opts = proplists:get_value(options, CompileInfo, []), + true = lists:member({d, 'EUNIT'}, Opts) + end + end, + lists:foreach(Macro, [basic_app, basic_app_tests, basic_app_tests_helper]). %% === tests for multiple applications in the `apps' directory of a project === @@ -220,7 +239,19 @@ multi_app_testset(Config) -> {module, multi_app_tests_helper}]}, Set = rebar_prv_eunit:prepare_tests(Result). - +multi_app_eunit_macro(_Config) -> + Macro = fun(Mod) -> + begin + Path = code:which(Mod), + {ok, {Mod, [{compile_info, CompileInfo}]}} = beam_lib:chunks(Path, [compile_info]), + Opts = proplists:get_value(options, CompileInfo, []), + true = lists:member({d, 'EUNIT'}, Opts) + end + end, + lists:foreach(Macro, [multi_app_bar, multi_app_bar_tests, + multi_app_baz, multi_app_baz_tests, + multi_app_tests, multi_app_tests_helper, + multi_app_bar_tests_helper, multi_app_baz_tests_helper]). %% === tests for command line arguments === diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index fb7b140..a31a4c9 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -377,8 +377,7 @@ test_profile_applied_at_completion(Config) -> [App] = rebar_state:project_apps(State), ErlOpts = rebar_app_info:get(App, erl_opts), - true = lists:member({d, 'TEST'}, ErlOpts), - true = lists:member({d, 'EUNIT'}, ErlOpts). + true = lists:member({d, 'TEST'}, ErlOpts). test_profile_applied_before_compile(Config) -> AppDir = ?config(apps, Config), @@ -394,9 +393,7 @@ test_profile_applied_before_compile(Config) -> code:add_paths(rebar_state:code_paths(State, all_deps)), S = list_to_atom("not_a_real_src_" ++ Name), - Opts = proplists:get_value(options, S:module_info(compile), []), - true = lists:member({d, 'TEST'}, Opts), - true = lists:member({d, 'EUNIT'}, Opts). + true = lists:member({d, 'TEST'}, proplists:get_value(options, S:module_info(compile), [])). test_profile_applied_before_eunit(Config) -> AppDir = ?config(apps, Config), @@ -412,9 +409,7 @@ test_profile_applied_before_eunit(Config) -> code:add_paths(rebar_state:code_paths(State, all_deps)), T = list_to_atom("not_a_real_src_" ++ Name ++ "_tests"), - Opts = proplists:get_value(options, T:module_info(compile), []), - true = lists:member({d, 'TEST'}, Opts), - true = lists:member({d, 'EUNIT'}, Opts). + true = lists:member({d, 'TEST'}, proplists:get_value(options, T:module_info(compile), [])). test_profile_applied_to_apps(Config) -> AppDir = ?config(apps, Config), @@ -435,6 +430,5 @@ test_profile_applied_to_apps(Config) -> lists:foreach(fun(App) -> Opts = rebar_app_info:opts(App), ErlOpts = dict:fetch(erl_opts, Opts), - true = lists:member({d, 'TEST'}, ErlOpts), - true = lists:member({d, 'EUNIT'}, ErlOpts) + true = lists:member({d, 'TEST'}, ErlOpts) end, Apps). |