From 47a6b5981d41be62942ce06eea0b788a949d66f8 Mon Sep 17 00:00:00 2001 From: Pablo Costas Date: Thu, 6 Aug 2020 19:20:23 +0200 Subject: [PATCH] Fix keep_logs option crashing when having more than N directories rebar3 would crash if the option `{keep_logs, N}` was present and there were more than N run directories in the log dir, so if the option is found we keep the N-1 newest directories and delete the rest. While we are at it, as this should fix the crash, let's limit the number of logs runs to keep from test runs in rebar3 to 5. --- rebar.config | 3 +++ src/rebar_prv_common_test.erl | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/rebar.config b/rebar.config index d166b5d4..12e80b11 100644 --- a/rebar.config +++ b/rebar.config @@ -49,6 +49,9 @@ {exclude_mods, [rebar_prv_alias]} ]}. +%% Keep only the logs of the last 5 runs +{ct_opts, [{keep_logs, 5}]}. + %% Profiles {profiles, [{test, [ {deps, [{meck, "0.8.13"}]}, diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index 6f4050ae..6d9f37e7 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -686,12 +686,38 @@ translate(State, [], Path) -> {error, badparent} -> Path end. +-spec handle_keep_logs(file:filename(), pos_integer()) -> ok. +handle_keep_logs(LogDir, N) -> + case file:list_dir(LogDir) of + {ok, Filenames} -> + Dirs = lists:filter(fun(File) -> + filelib:is_dir(filename:join([LogDir, File])) + end, Filenames) -- ["last"], %% we ignore the symlink as we later handle it + case Dirs of + %% first time running the tests, there are no logs to delete + [] -> ok; + _ -> + SortedDirs = lists:reverse(lists:sort(Dirs)), + %% sort the log dirs and keep the N - 1 newest + {_Keep, Discard} = lists:split(N - 1, SortedDirs), + ?DEBUG("Removing the following directories because keep_logs option was found: ~p", [Discard]), + [rebar_file_utils:rm_rf(filename:join([LogDir, Dir])) || Dir <- Discard], + ok + end; + _ -> ok + end. + setup_logdir(State, Opts) -> Logdir = case proplists:get_value(logdir, Opts) of undefined -> filename:join([rebar_dir:base_dir(State), "logs"]); Dir -> Dir end, filelib:ensure_dir(filename:join([Logdir, "dummy.beam"])), + case proplists:get_value(keep_logs, Opts) of + all -> ok; + undefined -> ok; + N -> handle_keep_logs(Logdir, N) + end, [{logdir, Logdir}|lists:keydelete(logdir, 1, Opts)]. turn_off_auto_compile(Opts) ->