Skip to content

Instantly share code, notes, and snippets.

@joewilliams
Created February 3, 2011 22:32
Show Gist options
  • Save joewilliams/810368 to your computer and use it in GitHub Desktop.
Save joewilliams/810368 to your computer and use it in GitHub Desktop.
-module(genappup).
-export([run/1]).
run(OldReleaseDir) ->
%% Get the release name and version
{Name, _Ver} = get_release_name(filename:join(["rel", "reltool.config"])),
%% Get lists of the old and new app files
OldAppFiles = rebar_utils:find_files(
filename:join([OldReleaseDir, "lib"]), "^.*.app$"),
NewAppFiles = rebar_utils:find_files(
filename:join(["rel", Name, "lib"]), "^.*.app$"),
%% Find all the apps that have been upgraded
UpgradedApps = get_upgraded_apps(OldAppFiles, NewAppFiles),
%% Get a list of any appup files that exist in the new release
NewAppUpFiles = rebar_utils:find_files(
filename:join(["rel", Name, "lib"]), "^.*.appup"),
%% Convert the list of appup files into app names
AppUpApps = appup_apps(NewAppUpFiles),
%% Create a list of apps that don't have appups already
GenAppUpApps = genappup_which_apps(UpgradedApps, AppUpApps),
%% Generate appup files
generate_appups(Name, GenAppUpApps).
get_release_name(ReltoolFile) ->
%% expect sys to be the first proplist in reltool.config
case file:consult(ReltoolFile) of
{ok, [{sys, Config}| _]} ->
%% expect the first rel in the proplist to be the one you want
{rel, Name, Ver, _} = proplists:lookup(rel, Config),
{Name, Ver};
_ ->
io:format("Failed to parse ~s~n", [ReltoolFile])
end.
get_upgraded_apps(OldAppFiles, NewAppFiles) ->
OldAppsVer = [get_app_version(AppFile) || AppFile <- OldAppFiles],
NewAppsVer = [get_app_version(AppFile) || AppFile <- NewAppFiles],
UpgradedApps = lists:subtract(NewAppsVer, OldAppsVer),
lists:map(
fun({App, NewVer}) ->
{App, OldVer} = proplists:lookup(App, OldAppsVer),
{App, {OldVer, NewVer}}
end,
UpgradedApps).
get_app_version(File) ->
case file:consult(File) of
{ok,[{application, Name,[_,{vsn,Ver}|_]}]} ->
{Name, Ver};
_ ->
io:format("Failed to parse ~s~n", [File])
end.
appup_apps(NewAppUpFiles) ->
lists:map(
fun(File) ->
Pos1 = string:rchr(File, $/),
Pos2 = string:rchr(File, $.),
string:sub_string(File, Pos1 + 1, Pos2 - 1)
end,
NewAppUpFiles).
genappup_which_apps(UpgradedApps, [First|Rest]) ->
List = proplists:delete(list_to_atom(First), UpgradedApps),
genappup_which_apps(List, Rest);
genappup_which_apps(Apps, []) ->
Apps.
generate_appups(Name, [{App, {OldVer, NewVer}}|Rest]) ->
AppUpFile = filename:join(
[".", "rel", Name, "lib",
atom_to_list(App) ++ "-" ++ NewVer, "ebin",
atom_to_list(App) ++ ".appup"]),
ok = file:write_file(AppUpFile,
io_lib:fwrite("%% appup generated for ~p by your friend rebar (~p)\n"
"{~p, [{~p, []}], [{~p, []}]}.\n",
[App, rebar_utils:now_str(), NewVer, OldVer, OldVer])),
io:format("generated appup for ~p~n", [App]),
generate_appups(Name, Rest);
generate_appups(_, []) ->
io:format("done~n", []).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment