Packages
geas
2.7.13
2.11.1
2.11.0
retired
2.10.1
2.10.0
retired
2.9.9
2.9.8
2.9.7
2.9.6
2.9.5
2.9.4
2.9.2
2.9.1
2.9.0
2.8.1
2.8.0
2.7.14
2.7.13
2.7.12
2.7.11
2.7.10
2.7.9
2.7.8
2.7.7
2.7.6
2.7.5
2.7.4
2.7.3
2.7.2
2.7.1
2.7.0
2.6.2
2.6.1
2.6.0
retired
2.5.1
2.5.0
retired
2.4.6
2.4.5
retired
2.4.4
retired
2.4.3
retired
2.4.2
retired
2.4.1
retired
2.4.0
2.3.0
2.2.0
Guess Erlang Application Scattering
Current section
Files
Jump to
Current section
Files
src/geas_patches.hrl
%%-------------------------------------------------------------------------
%% @doc List currently installed patches
%% @end
%%-------------------------------------------------------------------------
list_installed_patches(undefined) -> [];
list_installed_patches(Current) ->
P = list_potential_patches(Current),
% For each potential patch, see if all updated application are found in lib_dir
A =lists:foldl(fun({L, R}, Acc) ->
case lists:all(fun(X)-> [Nameb, _] = binary:split(list_to_binary(X), <<"-">>, ?SPLIT_OPTS),
Name = list_to_atom(binary_to_list(Nameb)),
code:lib_dir(Name) == filename:join(code:lib_dir(), X)
end , R) of
false -> Acc ;
true -> lists:flatten(Acc ++ [list_to_atom(L)])
end
end, [], P),
lists:flatmap(fun(X) -> [atom_to_list(X)] end, A).
%%-------------------------------------------------------------------------
%% @doc List possible patches for current release
%% @end
%%-------------------------------------------------------------------------
list_potential_patches(Current)
->
S = filename:join([get(geas_cwd),code:priv_dir(geas), "otp_versions.table"]),
list_potential_patches(Current, S).
list_potential_patches(Current, S) ->
O = parse_otp_table(S),
{Poss, _} = lists:partition(fun({L, _R}) ->
% Keep L when not current release
case L of
Current -> false ;
_ -> % Keep L when a patche of current release
lists:prefix(Current, L)
end
end, O),
Poss.
%%-------------------------------------------------------------------------
%% @doc Parse otp_versions.table
%% @end
%%-------------------------------------------------------------------------
parse_otp_table(S)
when is_list(S)
->
{ok, B} = file:read_file(S),
Raw = binary:split(B, <<"\n">>, ?SPLIT_OPTS),
Net = lists:foldl(fun(X, Acc) ->
case X of
<<>> -> [];
_ ->
[N | _] = binary:split(X, <<"#">>,?SPLIT_OPTS),
[L, R] = binary:split(N, <<":">>, ?SPLIT_OPTS),
[_, V] = binary:split(L, <<"-">>, ?SPLIT_OPTS),
P_ = binary:split(R, <<" ">>, ?SPLIT_OPTS),
P = lists:flatmap(fun(Z) -> [erlang:binary_to_list(Z)] end, P_),
Acc ++ [{string:strip(erlang:binary_to_list(V)), P}]
end
end, [], Raw),
Net.
%%-------------------------------------------------------------------------
%% @doc Check if update OTP table is required
%% @note : simply remove file otp_versions.table in geas priv dir.
%% @end
%%-------------------------------------------------------------------------
check_update_otp_table(S) ->
% If required or if file does not exists, download it.
Conf = get_config(),
C1 = filelib:is_regular(S),
C2 = Conf#config.update ,
case ((C1 == false) or (C2 == true)) of
false -> ok ;
true ->
Str = Conf#config.http_opts ,
Opts = convert_str_to_term(Str),
application:start(inets),
application:start(crypto),
application:start(asn1),
application:start(public_key),
application:start(ssl),
update_otp_table(S, Opts)
end.
%%-------------------------------------------------------------------------
%% @doc Update OTP table
%% @end
%%-------------------------------------------------------------------------
update_otp_table(S, Opts)
when is_list(S) ->
try
do_log({notice, httpc, "Trying to update OTP table"}),
ok = httpc:set_options(Opts),
{ok, {{_, 200, _}, _, Body}} =
httpc:request(get, {"https://raw.githubusercontent.com/erlang/otp/master/otp_versions.table", []}, [], []),
ok = file:delete(S),
ok = file:write_file(S, Body),
do_log({notice, httpc, "OTP table was updated"})
catch
_:Err ->
do_log({error, httpc, Err}),
ok
end.
%%-------------------------------------------------------------------------
%% @doc Get recommended patches
%% @end
%%-------------------------------------------------------------------------
get_recommanded_patches(Current) ->
% List all applications used in current global code
C = get(geas_calls),
T = filename:join([get(geas_cwd),code:priv_dir(geas),"mod2app.term"]),
{ok, B} = file:read_file(T),
Term = erlang:binary_to_term(B),
Apps = lists:usort(lists:flatmap(fun({M, _, _}) ->
case lists:keyfind(M, 1, Term) of
false -> [];
{M, A} -> [A];
_ -> []
end
end, C)),
erlang:put(geas_apps, Apps),
log({notice, applications, Apps}),
% List patches higher than current version
S = filename:join([get(geas_cwd),code:priv_dir(geas), "otp_versions.table"]),
check_update_otp_table(S),
Ins = list_installed_patches(Current),
Pot = list_potential_patches(Current, S),
Candidats = lists:usort(lists:flatten(lists:flatmap(fun({P, L}) ->
case lists:member(P, Ins) of
true -> [];
false -> [{P, L}]
end
end , Pot))),
% For each patche, list application(s) that should be upgraded
R = lists:usort(lists:flatmap(fun({P, Al}) ->
%erlang:display({P, Al}),
[lists:usort(lists:flatmap(fun(A) ->
[A_ | _] = re:split(A,"-",[{return, list}]), % string:split available starting 20.0 !
case lists:member(erlang:list_to_atom(A_), Apps) of
false -> [];
true -> log({tip, {recommend, P}, A}),
[P]
end
end, Al))]
end, lists:reverse(Candidats))),
R.