|
|
@ -0,0 +1,90 @@ |
|
|
|
%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- |
|
|
|
%% ex: ts=4 sw=4 et |
|
|
|
|
|
|
|
-module(rebar_prv_local_install). |
|
|
|
|
|
|
|
-behaviour(provider). |
|
|
|
|
|
|
|
-export([init/1, |
|
|
|
do/1, |
|
|
|
format_error/1]). |
|
|
|
|
|
|
|
-export([extract_escript/2]). |
|
|
|
|
|
|
|
-include("rebar.hrl"). |
|
|
|
-include_lib("kernel/include/file.hrl"). |
|
|
|
|
|
|
|
-define(PROVIDER, install). |
|
|
|
-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 local install"}, |
|
|
|
{short_desc, "Extract libs from rebar3 escript along with a run script."}, |
|
|
|
{desc, ""}, |
|
|
|
{opts, []}])), |
|
|
|
{ok, State1}. |
|
|
|
|
|
|
|
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. |
|
|
|
do(State) -> |
|
|
|
case rebar_state:escript_path(State) of |
|
|
|
undefined -> |
|
|
|
?INFO("Already running from an unpacked rebar3. Nothing to do...", []), |
|
|
|
{ok, State}; |
|
|
|
ScriptPath -> |
|
|
|
extract_escript(State, ScriptPath) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec format_error(any()) -> iolist(). |
|
|
|
format_error(Reason) -> |
|
|
|
io_lib:format("~p", [Reason]). |
|
|
|
|
|
|
|
bin_contents(OutputDir) -> |
|
|
|
<<" |
|
|
|
#!/usr/bin/env sh |
|
|
|
|
|
|
|
erl -pa ", (ec_cnv:to_binary(OutputDir))/binary,"/*/ebin +sbtu +A0 -noinput -boot start_clean -s rebar3 main -extra \"$@\" |
|
|
|
">>. |
|
|
|
|
|
|
|
extract_escript(State, ScriptPath) -> |
|
|
|
{ok, Escript} = escript:extract(ScriptPath, []), |
|
|
|
{archive, Archive} = lists:keyfind(archive, 1, Escript), |
|
|
|
|
|
|
|
%% Extract contents of Archive to ~/.cache/rebar3/lib |
|
|
|
%% And add a rebar3 bin script to ~/.cache/rebar3/bin |
|
|
|
Opts = rebar_state:opts(State), |
|
|
|
OutputDir = filename:join(rebar_dir:global_cache_dir(Opts), "lib"), |
|
|
|
filelib:ensure_dir(filename:join(OutputDir, "empty")), |
|
|
|
|
|
|
|
?INFO("Extracting rebar3 libs to ~s...", [OutputDir]), |
|
|
|
zip:extract(Archive, [{cwd, OutputDir}]), |
|
|
|
|
|
|
|
BinDir = filename:join(rebar_dir:global_cache_dir(Opts), "bin"), |
|
|
|
BinFile = filename:join(BinDir, "rebar3"), |
|
|
|
filelib:ensure_dir(BinFile), |
|
|
|
|
|
|
|
{ok, #file_info{mode = _, |
|
|
|
uid = Uid, |
|
|
|
gid = Gid}} = file:read_file_info(ScriptPath, [mode, uid, gid]), |
|
|
|
|
|
|
|
?INFO("Writing rebar3 run script ~s...", [BinFile]), |
|
|
|
file:write_file(BinFile, bin_contents(OutputDir)), |
|
|
|
ok = file:write_file_info(BinFile, #file_info{mode=33277, |
|
|
|
uid=Uid, |
|
|
|
gid=Gid}), |
|
|
|
|
|
|
|
?INFO("Add to $PATH for use: export PATH=$PATH:~s", [BinDir]), |
|
|
|
|
|
|
|
{ok, State}. |