소스 검색

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.
Thales Macedo Garitezi 4 년 전
부모
커밋
3ff6661a58
1개의 변경된 파일40개의 추가작업 그리고 16개의 파일을 삭제
  1. 40 16
      scripts/update_appup.escript

+ 40 - 16
scripts/update_appup.escript

@@ -189,8 +189,11 @@ find_appup_actions(CurrApps, PrevApps) ->
     maps:fold(
     maps:fold(
       fun(App, CurrAppIdx, Acc) ->
       fun(App, CurrAppIdx, Acc) ->
               case PrevApps of
               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
       end,
       end,
       [],
       [],
@@ -214,10 +217,10 @@ find_appup_actions(App, CurrAppIdx, PrevAppIdx = #app{version = PrevVersion}) ->
 %% in their current appup.
 %% in their current appup.
 diff_appup_instructions(ComputedChanges, PresentChanges) ->
 diff_appup_instructions(ComputedChanges, PresentChanges) ->
     lists:foldr(
     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 ->
                   undefined ->
-                      [{Vsn, ComputedActions} | Acc];
+                      [{VsnOrRegex, ComputedActions} | Acc];
                   PresentActions ->
                   PresentActions ->
                       DiffActions = ComputedActions -- PresentActions,
                       DiffActions = ComputedActions -- PresentActions,
                       case DiffActions of
                       case DiffActions of
@@ -225,7 +228,7 @@ diff_appup_instructions(ComputedChanges, PresentChanges) ->
                               %% no diff
                               %% no diff
                               Acc;
                               Acc;
                           _ ->
                           _ ->
-                              [{Vsn, DiffActions} | Acc]
+                              [{VsnOrRegex, DiffActions} | Acc]
                       end
                       end
               end
               end
       end,
       end,
@@ -250,8 +253,11 @@ parse_appup_diffs(Upgrade, OldUpgrade, Downgrade, OldDowngrade) ->
     end.
     end.
 
 
 %% TODO: handle regexes
 %% 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) ->
 find_old_appup_actions(App, PrevVersion) ->
     {Upgrade0, Downgrade0} =
     {Upgrade0, Downgrade0} =
@@ -279,11 +285,11 @@ merge_update_actions(App, Changes, Vsns) ->
     lists:map(fun(Ret = {<<".*">>, _}) ->
     lists:map(fun(Ret = {<<".*">>, _}) ->
                       Ret;
                       Ret;
                  ({Vsn, Actions}) ->
                  ({Vsn, Actions}) ->
-                      {Vsn, do_merge_update_actions(App, Changes, Actions)}
+                      {Vsn, do_merge_update_actions(App, Vsn, Changes, Actions)}
               end,
               end,
               Vsns).
               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,
     AppSpecific = app_specific_actions(App) -- OldActions,
     AlreadyHandled = lists:flatten(lists:map(fun process_old_action/1, OldActions)),
     AlreadyHandled = lists:flatten(lists:map(fun process_old_action/1, OldActions)),
     New = New0 -- AlreadyHandled,
     New = New0 -- AlreadyHandled,
@@ -308,14 +314,30 @@ process_old_action(_) ->
     [].
     [].
 
 
 ensure_version(Version, OldInstructions) ->
 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 ->
         false ->
-            [{Version, []}|OldInstructions];
+            [{Version, []} | OldInstructions];
         _ ->
         _ ->
             OldInstructions
             OldInstructions
     end.
     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) ->
 read_appup(File) ->
     %% NOTE: appup file is a script, it may contain variables or functions.
     %% NOTE: appup file is a script, it may contain variables or functions.
     case file:script(File, [{'VSN', "VSN"}]) of
     case file:script(File, [{'VSN', "VSN"}]) of
@@ -398,16 +420,18 @@ index_app(AppFile) ->
               , modules       = Modules
               , 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} =
     {New, Changed} =
         maps:fold( fun(Mod, MD5, {New, Changed}) ->
         maps:fold( fun(Mod, MD5, {New, Changed}) ->
                            case OldModules of
                            case OldModules of
                                #{Mod := OldMD5} when MD5 =:= OldMD5 ->
                                #{Mod := OldMD5} when MD5 =:= OldMD5 ->
                                    {New, Changed};
                                    {New, Changed};
                                #{Mod := _} ->
                                #{Mod := _} ->
-                                   {New, [Mod|Changed]};
+                                   {New, [Mod | Changed]};
                                _ ->
                                _ ->
-                                   {[Mod|New], Changed}
+                                   {[Mod | New], Changed}
                            end
                            end
                    end
                    end
                  , {[], []}
                  , {[], []}