From 3ff6661a589186ebae16db2bbe12ea290c2a0ced Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Fri, 17 Dec 2021 14:48:41 -0300 Subject: [PATCH] chore(update_appup): take regexes into account when comparing vsns This change makes the `update_appup.escript` check whether the new version of an application (the _current_ one) is already contained in entries in the _new_ .appup file for that application if such .appup file contains regexes. NOTE: this does not cover the case in which we calculate the difference between _old_ and _new_ appup entries, and those consist of regexes. In such case, we would need to check if one regex is "contained" in the other, which is not currently supported by this patch. --- scripts/update_appup.escript | 56 +++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/scripts/update_appup.escript b/scripts/update_appup.escript index 7674a941c..df2f2b164 100755 --- a/scripts/update_appup.escript +++ b/scripts/update_appup.escript @@ -189,8 +189,11 @@ find_appup_actions(CurrApps, PrevApps) -> maps:fold( fun(App, CurrAppIdx, Acc) -> case PrevApps of - #{App := PrevAppIdx} -> find_appup_actions(App, CurrAppIdx, PrevAppIdx) ++ Acc; - _ -> Acc %% New app, nothing to upgrade here. + #{App := PrevAppIdx} -> + find_appup_actions(App, CurrAppIdx, PrevAppIdx) ++ Acc; + _ -> + %% New app, nothing to upgrade here. + Acc end end, [], @@ -214,10 +217,10 @@ find_appup_actions(App, CurrAppIdx, PrevAppIdx = #app{version = PrevVersion}) -> %% in their current appup. diff_appup_instructions(ComputedChanges, PresentChanges) -> lists:foldr( - fun({Vsn, ComputedActions}, Acc) -> - case find_matching_version(Vsn, PresentChanges) of + fun({VsnOrRegex, ComputedActions}, Acc) -> + case find_matching_version(VsnOrRegex, PresentChanges) of undefined -> - [{Vsn, ComputedActions} | Acc]; + [{VsnOrRegex, ComputedActions} | Acc]; PresentActions -> DiffActions = ComputedActions -- PresentActions, case DiffActions of @@ -225,7 +228,7 @@ diff_appup_instructions(ComputedChanges, PresentChanges) -> %% no diff Acc; _ -> - [{Vsn, DiffActions} | Acc] + [{VsnOrRegex, DiffActions} | Acc] end end end, @@ -250,8 +253,11 @@ parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) -> end. %% TODO: handle regexes -find_matching_version(Vsn, PresentChanges) -> - proplists:get_value(Vsn, PresentChanges). +%% Since the first argument may be a regex itself, we would need to +%% check if it is "contained" within other regexes inside list of +%% versions in the second argument. +find_matching_version(VsnOrRegex, PresentChanges) -> + proplists:get_value(VsnOrRegex, PresentChanges). find_old_appup_actions(App, PrevVersion) -> {Upgrade0, Downgrade0} = @@ -279,11 +285,11 @@ merge_update_actions(App, Changes, Vsns) -> lists:map(fun(Ret = {<<".*">>, _}) -> Ret; ({Vsn, Actions}) -> - {Vsn, do_merge_update_actions(App, Changes, Actions)} + {Vsn, do_merge_update_actions(App, Vsn, Changes, Actions)} end, Vsns). -do_merge_update_actions(App, {New0, Changed0, Deleted0}, OldActions) -> +do_merge_update_actions(App, Vsn, {New0, Changed0, Deleted0}, OldActions) -> AppSpecific = app_specific_actions(App) -- OldActions, AlreadyHandled = lists:flatten(lists:map(fun process_old_action/1, OldActions)), New = New0 -- AlreadyHandled, @@ -308,14 +314,30 @@ process_old_action(_) -> []. ensure_version(Version, OldInstructions) -> - OldVersions = [ensure_string(element(1, I)) || I <- OldInstructions], - case lists:member(Version, OldVersions) of + OldVersions = [element(1, I) || I <- OldInstructions], + case contains_version(Version, OldVersions) of false -> - [{Version, []}|OldInstructions]; + [{Version, []} | OldInstructions]; _ -> OldInstructions end. +contains_version(Needle, Haystack) when is_list(Needle) -> + lists:any( + fun(Regex) when is_binary(Regex) -> + case re:run(Needle, Regex) of + {match, _} -> + true; + nomatch -> + false + end; + (Needle) -> + true; + (_) -> + false + end, + Haystack). + read_appup(File) -> %% NOTE: appup file is a script, it may contain variables or functions. case file:script(File, [{'VSN', "VSN"}]) of @@ -398,16 +420,18 @@ index_app(AppFile) -> , modules = Modules }}. -diff_app(App, #app{version = NewVersion, modules = NewModules}, #app{version = OldVersion, modules = OldModules}) -> +diff_app(App, + #app{version = NewVersion, modules = NewModules}, + #app{version = OldVersion, modules = OldModules}) -> {New, Changed} = maps:fold( fun(Mod, MD5, {New, Changed}) -> case OldModules of #{Mod := OldMD5} when MD5 =:= OldMD5 -> {New, Changed}; #{Mod := _} -> - {New, [Mod|Changed]}; + {New, [Mod | Changed]}; _ -> - {[Mod|New], Changed} + {[Mod | New], Changed} end end , {[], []}