update_appup.escript 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #!/usr/bin/env -S escript -c
  2. %% A script that adds changed modules to the corresponding appup files
  3. main(_Args) ->
  4. ChangedFiles = string:lexemes(os:cmd("git diff --name-only origin/master..HEAD"), "\n"),
  5. AppModules = group_modules(lists:filtermap(fun filter_erlang_modules/1, ChangedFiles)),
  6. io:format("Changed modules: ~p~n", [AppModules]),
  7. _ = maps:map(fun process_app/2, AppModules),
  8. ok.
  9. process_app(App, Modules) ->
  10. AppupFiles = filelib:wildcard(lists:concat(["{src,apps,lib-*}/**/", App, ".appup.src"])),
  11. case AppupFiles of
  12. [AppupFile] ->
  13. update_appup(AppupFile, Modules);
  14. [] ->
  15. io:format("~nWARNING: Please create an stub appup src file for ~p~n", [App])
  16. end.
  17. filter_erlang_modules(Filename) ->
  18. case lists:reverse(filename:split(Filename)) of
  19. [Module, "src"] ->
  20. erl_basename("emqx", Module);
  21. [Module, "src", App|_] ->
  22. erl_basename(App, Module);
  23. [Module, _, "src", App|_] ->
  24. erl_basename(App, Module);
  25. _ ->
  26. false
  27. end.
  28. erl_basename(App, Name) ->
  29. case filename:basename(Name, ".erl") of
  30. Name -> false;
  31. Module -> {true, {list_to_atom(App), list_to_atom(Module)}}
  32. end.
  33. group_modules(L) ->
  34. lists:foldl(fun({App, Mod}, Acc) ->
  35. maps:update_with(App, fun(Tl) -> [Mod|Tl] end, [Mod], Acc)
  36. end, #{}, L).
  37. update_appup(File, Modules) ->
  38. io:format("~nUpdating appup: ~p~n", [File]),
  39. {_, Upgrade0, Downgrade0} = read_appup(File),
  40. Upgrade = update_actions(Modules, Upgrade0),
  41. Downgrade = update_actions(Modules, Downgrade0),
  42. IOList = io_lib:format("%% -*- mode: erlang -*-
  43. {VSN,~n ~p,~n ~p}.~n", [Upgrade, Downgrade]),
  44. ok = file:write_file(File, IOList).
  45. update_actions(Modules, Versions) ->
  46. lists:map(fun(L) -> do_update_actions(Modules, L) end, Versions).
  47. do_update_actions(_, Ret = {<<".*">>, _}) ->
  48. Ret;
  49. do_update_actions(Modules, {Vsn, Actions}) ->
  50. {Vsn, add_modules(Modules, Actions)}.
  51. add_modules(NewModules, OldActions) ->
  52. OldModules = lists:map(fun(It) -> element(2, It) end, OldActions),
  53. Modules = NewModules -- OldModules,
  54. OldActions ++ [{load_module, M, brutal_purge, soft_purge, []} || M <- Modules].
  55. read_appup(File) ->
  56. {ok, Bin0} = file:read_file(File),
  57. %% Hack:
  58. Bin1 = re:replace(Bin0, "VSN", "\"VSN\""),
  59. TmpFile = filename:join("/tmp", filename:basename(File)),
  60. ok = file:write_file(TmpFile, Bin1),
  61. {ok, [Terms]} = file:consult(TmpFile),
  62. Terms.