No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

95 líneas
3.3 KiB

  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. -module(rebar_prv_local_install).
  4. -behaviour(provider).
  5. -export([init/1,
  6. do/1,
  7. format_error/1]).
  8. -export([extract_escript/2]).
  9. -include("rebar.hrl").
  10. -include_lib("kernel/include/file.hrl").
  11. -define(PROVIDER, install).
  12. -define(NAMESPACE, local).
  13. -define(DEPS, []).
  14. %% ===================================================================
  15. %% Public API
  16. %% ===================================================================
  17. -spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
  18. init(State) ->
  19. State1 =
  20. rebar_state:add_provider(State,
  21. providers:create([{name, ?PROVIDER},
  22. {module, ?MODULE},
  23. {bare, true},
  24. {namespace, ?NAMESPACE},
  25. {deps, ?DEPS},
  26. {example, "rebar3 unstable install"},
  27. {short_desc, "Extract libs from rebar3 escript along with a run script."},
  28. {desc, ""},
  29. {opts, []}])),
  30. {ok, State1}.
  31. -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
  32. do(State) ->
  33. case os:type() of
  34. {win32, _} ->
  35. ?ERROR("Sorry, this feature is not yet available on Windows.", []),
  36. {ok, State};
  37. _ ->
  38. case rebar_state:escript_path(State) of
  39. undefined ->
  40. ?INFO("Already running from an unpacked rebar3. Nothing to do...", []),
  41. {ok, State};
  42. ScriptPath ->
  43. extract_escript(State, ScriptPath)
  44. end
  45. end.
  46. -spec format_error(any()) -> iolist().
  47. format_error(Reason) ->
  48. io_lib:format("~p", [Reason]).
  49. bin_contents(OutputDir) ->
  50. <<"#!/usr/bin/env sh
  51. erl -pz ", (ec_cnv:to_binary(OutputDir))/binary,"/*/ebin +sbtu +A0 -noshell -boot start_clean -s rebar3 main $REBAR3_ERL_ARGS -extra \"$@\"
  52. ">>.
  53. extract_escript(State, ScriptPath) ->
  54. {ok, Escript} = escript:extract(ScriptPath, []),
  55. {archive, Archive} = lists:keyfind(archive, 1, Escript),
  56. %% Extract contents of Archive to ~/.cache/rebar3/lib
  57. %% And add a rebar3 bin script to ~/.cache/rebar3/bin
  58. Opts = rebar_state:opts(State),
  59. OutputDir = filename:join(rebar_dir:global_cache_dir(Opts), "lib"),
  60. filelib:ensure_dir(filename:join(OutputDir, "empty")),
  61. ?INFO("Extracting rebar3 libs to ~s...", [OutputDir]),
  62. zip:extract(Archive, [{cwd, OutputDir}]),
  63. BinDir = filename:join(rebar_dir:global_cache_dir(Opts), "bin"),
  64. BinFile = filename:join(BinDir, "rebar3"),
  65. filelib:ensure_dir(BinFile),
  66. {ok, #file_info{mode = _,
  67. uid = Uid,
  68. gid = Gid}} = file:read_file_info(ScriptPath),
  69. ?INFO("Writing rebar3 run script ~s...", [BinFile]),
  70. file:write_file(BinFile, bin_contents(OutputDir)),
  71. ok = file:write_file_info(BinFile, #file_info{mode=33277,
  72. uid=Uid,
  73. gid=Gid}),
  74. ?INFO("Add to $PATH for use: export PATH=$PATH:~s", [BinDir]),
  75. {ok, State}.