瀏覽代碼

Allow cleaning specific apps or deps only

This will allow project with larger dependencies sets to clean only the
apps they want to when testing or changing small things, rather than
forcing a rebuild of the whole dep set.

Also allows cleaning up apps, not just deps.
pull/2173/head
Fred Hebert 5 年之前
父節點
當前提交
936c8b1ba9
共有 2 個文件被更改,包括 63 次插入14 次删除
  1. +30
    -13
      src/rebar_prv_clean.erl
  2. +33
    -1
      test/rebar_compile_SUITE.erl

+ 30
- 13
src/rebar_prv_clean.erl 查看文件

@ -28,28 +28,32 @@ init(State) ->
{short_desc, "Remove compiled beam files from apps."},
{desc, "Remove compiled beam files from apps."},
{opts, [{all, $a, "all", undefined, "Clean all apps include deps"},
{apps, undefined, "apps", string, "Clean a specific list of apps or dependencies"},
{profile, $p, "profile", string, "Clean under profile. Equivalent to `rebar3 as <profile> clean`"}]}])),
{ok, State1}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
Providers = rebar_state:providers(State),
{All, Profiles} = handle_args(State),
{All, Profiles, Specific} = handle_args(State),
State1 = rebar_state:apply_profiles(State, [list_to_atom(X) || X <- Profiles]),
Cwd = rebar_dir:get_cwd(),
rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State1),
case All of
true ->
DepsDir = rebar_dir:deps_dir(State1),
DepsDirs = filelib:wildcard(filename:join(DepsDir, "*")),
AllApps = rebar_app_discover:find_apps(DepsDirs, all),
clean_apps(State1, Providers, AllApps);
false ->
ProjectApps = rebar_state:project_apps(State1),
clean_apps(State1, Providers, ProjectApps)
if All; Specific =/= [] ->
DepsDir = rebar_dir:deps_dir(State1),
DepsDirs = filelib:wildcard(filename:join(DepsDir, "*")),
AllApps = rebar_app_discover:find_apps(DepsDirs, all),
Filter = case All of
true -> fun(_) -> true end;
false -> fun(AppInfo) -> filter_name(AppInfo, Specific) end
end,
clean_apps(State1, Providers, AllApps, Filter);
true ->
ProjectApps = rebar_state:project_apps(State1),
clean_apps(State1, Providers, ProjectApps, fun(_) -> true end)
end,
clean_extras(State1),
@ -66,7 +70,7 @@ format_error(Reason) ->
%% Internal functions
%% ===================================================================
clean_apps(State, Providers, Apps) ->
clean_apps(State, Providers, Apps, Filter) ->
Compilers = rebar_state:compilers(State),
[begin
?INFO("Cleaning out ~ts...", [rebar_app_info:name(AppInfo)]),
@ -74,7 +78,7 @@ clean_apps(State, Providers, Apps) ->
AppInfo1 = rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, AppInfo, State),
rebar_compiler:clean(Compilers, AppInfo1),
rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo1, State)
end || AppInfo <- Apps].
end || AppInfo <- Apps, Filter(AppInfo)].
clean_extras(State) ->
BaseDir = rebar_dir:base_dir(State),
@ -84,4 +88,17 @@ handle_args(State) ->
{Args, _} = rebar_state:command_parsed_args(State),
All = proplists:get_value(all, Args, false),
Profiles = proplists:get_all_values(profile, Args),
{All, Profiles}.
DepsRaw = proplists:get_value(apps, Args),
Deps = parse_deps(DepsRaw),
{All, Profiles, Deps}.
parse_deps(undefined) -> [];
parse_deps(Bin) ->
case lists:usort(re:split(Bin, <<" *, *">>, [trim, unicode])) of
[<<"">>] -> []; % nothing submitted
Other -> Other
end.
filter_name(AppInfo, Names) ->
Name = rebar_app_info:name(AppInfo),
lists:member(Name, Names).

+ 33
- 1
test/rebar_compile_SUITE.erl 查看文件

@ -24,7 +24,7 @@ all() ->
deps_in_path, checkout_priority, highest_version_of_pkg_dep,
parse_transform_test, erl_first_files_test, mib_test,
umbrella_mib_first_test, only_default_transitive_deps, clean_all,
profile_deps, deps_build_in_prod, only_deps,
clean_specific, profile_deps, deps_build_in_prod, only_deps,
override_deps, override_add_deps, override_del_deps,
override_opts, override_add_opts, override_del_opts,
apply_overrides_exactly_once, override_only_deps,
@ -1351,6 +1351,38 @@ clean_all(Config) ->
{app, DepName, invalid},
{app, PkgName, invalid}]}).
clean_specific(Config) ->
AppDir = ?config(apps, Config),
Name = rebar_test_utils:create_random_name("app1_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
DepName = rebar_test_utils:create_random_name("dep1_"),
PkgName = rebar_test_utils:create_random_name("pkg1_"),
mock_git_resource:mock([]),
mock_pkg_resource:mock([
{pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
]),
RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
{list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
{list_to_atom(PkgName), Vsn}
]}]),
{ok, RConf} = file:consult(RConfFile),
%% Build things
rebar_test_utils:run_and_check(
Config, RConf, ["compile"],
{ok, [{app, Name}, {app, DepName}, {app, PkgName}]}
),
%% Clean all
rebar_test_utils:run_and_check(Config, [], ["clean", "--apps="++DepName++","++Name],
{ok, [{app, Name, invalid},
{app, DepName, invalid},
{app, PkgName, valid}]}).
override_deps(Config) ->
Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
TopDeps = rebar_test_utils:top_level_deps(Deps),

Loading…
取消
儲存