%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
|
%% ex: ts=4 sw=4 et
|
|
|
|
-module(rebar_prv_local_upgrade).
|
|
|
|
-behaviour(provider).
|
|
|
|
-export([init/1,
|
|
do/1,
|
|
format_error/1]).
|
|
|
|
-include("rebar.hrl").
|
|
-include_lib("providers/include/providers.hrl").
|
|
-include_lib("kernel/include/file.hrl").
|
|
|
|
-define(PROVIDER, upgrade).
|
|
-define(NAMESPACE, local).
|
|
-define(DEPS, []).
|
|
|
|
%% ===================================================================
|
|
%% Public API
|
|
%% ===================================================================
|
|
|
|
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
|
|
init(State) ->
|
|
State1 =
|
|
rebar_state:add_provider(State,
|
|
providers:create([{name, ?PROVIDER},
|
|
{module, ?MODULE},
|
|
{bare, true},
|
|
{namespace, ?NAMESPACE},
|
|
{deps, ?DEPS},
|
|
{example, "rebar3 unstable upgrade"},
|
|
{short_desc, "Download latest rebar3 escript and extract."},
|
|
{desc, ""},
|
|
{opts, []}])),
|
|
{ok, State1}.
|
|
|
|
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
|
|
do(State) ->
|
|
case os:type() of
|
|
{win32, _} ->
|
|
?ERROR("Sorry, this feature is not yet available on Windows.", []),
|
|
{ok, State};
|
|
_ ->
|
|
Md5 = case rebar_state:escript_path(State) of
|
|
undefined ->
|
|
false;
|
|
ScriptPath ->
|
|
get_md5(ScriptPath)
|
|
end,
|
|
|
|
case maybe_fetch_rebar3(Md5) of
|
|
{saved, TmpRebar3} ->
|
|
rebar_prv_local_install:extract_escript(State, TmpRebar3);
|
|
up_to_date ->
|
|
{ok, State};
|
|
Error ->
|
|
Error
|
|
end
|
|
end.
|
|
|
|
-spec format_error(any()) -> iolist().
|
|
format_error(bad_checksum) ->
|
|
"Not updating rebar3, the checksum of download did not match the one provided by s3.";
|
|
format_error(Reason) ->
|
|
io_lib:format("~p", [Reason]).
|
|
|
|
%% Internal
|
|
|
|
get_md5(Rebar3Path) ->
|
|
{ok, Rebar3File} = file:read_file(Rebar3Path),
|
|
Digest = crypto:hash(md5, Rebar3File),
|
|
DigestHex = lists:flatten([io_lib:format("~2.16.0B", [X]) || X <- binary_to_list(Digest)]),
|
|
string:to_lower(DigestHex).
|
|
|
|
maybe_fetch_rebar3(Rebar3Md5) ->
|
|
TmpDir = ec_file:insecure_mkdtemp(),
|
|
TmpFile = filename:join(TmpDir, "rebar3"),
|
|
case rebar_pkg_resource:request("https://s3.amazonaws.com/rebar3/rebar3", Rebar3Md5) of
|
|
{ok, Binary, ETag} ->
|
|
file:write_file(TmpFile, Binary),
|
|
case rebar_pkg_resource:etag(TmpFile) of
|
|
ETag ->
|
|
{saved, TmpFile};
|
|
_ ->
|
|
?PRV_ERROR(bad_checksum)
|
|
end;
|
|
error ->
|
|
?ERROR("Unable to fetch latest rebar3 escript. Please try again later.", []);
|
|
_ ->
|
|
?CONSOLE("No upgrade available", []),
|
|
up_to_date
|
|
end.
|