Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

170 rindas
6.0 KiB

pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
  1. #!/usr/bin/env escript
  2. %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
  3. %% ex: ft=erlang ts=4 sw=4 et
  4. main(_Args) ->
  5. %% Fetch and build deps required to build rebar3
  6. BaseDeps = [{providers, []}
  7. ,{getopt, []}
  8. ,{erlware_commons, ["ec_dictionary.erl", "ec_vsn.erl"]}],
  9. Deps = get_deps(),
  10. [fetch_and_compile(Dep, Deps) || Dep <- BaseDeps],
  11. %% Build rebar3 modules with compile:file
  12. bootstrap_rebar3(),
  13. %% Build rebar.app from rebar.app.src
  14. {ok, App} = rebar_app_info:new(rebar, "3.0.0", filename:absname("_build/default/lib/rebar/")),
  15. rebar_otp_app:compile(rebar_state:new(), App),
  16. %% Because we are compiling files that are loaded already we want to silence
  17. %% not_purged errors in rebar_erlc_compiler:opts_changed/1
  18. error_logger:tty(false),
  19. setup_env(),
  20. os:putenv("REBAR_PROFILE", "bootstrap"),
  21. {ok, State} = rebar3:run(["compile"]),
  22. reset_env(),
  23. os:putenv("REBAR_PROFILE", ""),
  24. %% Build erlydtl files (a hook on compile in the default profile) and escript file
  25. DepsPaths = rebar_state:code_paths(State, all_deps),
  26. code:add_pathsa(DepsPaths),
  27. rebar3:run(["clean", "-a"]),
  28. rebar3:run(["escriptize"]),
  29. %% Done with compile, can turn back on error logger
  30. error_logger:tty(true),
  31. %% Finally, update executable perms for our script on *nix,
  32. %% or write out script files on win32.
  33. ec_file:copy("_build/default/bin/rebar3", "./rebar3"),
  34. case os:type() of
  35. {unix,_} ->
  36. [] = os:cmd("chmod u+x rebar3"),
  37. ok;
  38. {win32,_} ->
  39. write_windows_scripts(),
  40. ok;
  41. _ ->
  42. ok
  43. end.
  44. fetch_and_compile({Name, ErlFirstFiles}, Deps) ->
  45. {Name, _, Repo} = lists:keyfind(Name, 1, Deps),
  46. ok = fetch(Repo, Name),
  47. compile(Name, ErlFirstFiles).
  48. fetch({git, Url, Source}, App) ->
  49. Dir = filename:join([filename:absname("_build/default/lib/"), App]),
  50. case filelib:is_dir(Dir) of
  51. true ->
  52. true = code:add_path(filename:join(Dir, "ebin")),
  53. ok;
  54. false ->
  55. fetch_source(Dir, Url, Source),
  56. ok
  57. end.
  58. fetch_source(Dir, Url, {ref, Ref}) ->
  59. ok = filelib:ensure_dir(Dir),
  60. os:cmd(io_lib:format("git clone ~s ~s", [Url, Dir])),
  61. {ok, Cwd} = file:get_cwd(),
  62. file:set_cwd(Dir),
  63. os:cmd(io_lib:format("git checkout -q ~s", [Ref])),
  64. file:set_cwd(Cwd);
  65. fetch_source(Dir, Url, {_, Branch}) ->
  66. ok = filelib:ensure_dir(Dir),
  67. os:cmd(io_lib:format("git clone ~s ~s -b ~s --single-branch",
  68. [Url, Dir, Branch])).
  69. compile(App, FirstFiles) ->
  70. Dir = filename:join(filename:absname("_build/default/lib/"), App),
  71. filelib:ensure_dir(filename:join([Dir, "ebin", "dummy.beam"])),
  72. code:add_path(filename:join(Dir, "ebin")),
  73. FirstFilesPaths = [filename:join([Dir, "src", Module]) || Module <- FirstFiles],
  74. Sources = FirstFilesPaths ++ filelib:wildcard(filename:join([Dir, "src", "*.erl"])),
  75. [compile_file(X, [{i, filename:join(Dir, "include")}
  76. ,{outdir, filename:join(Dir, "ebin")}
  77. ,return]) || X <- Sources].
  78. compile_file(File, Opts) ->
  79. case compile:file(File, Opts) of
  80. {ok, _Mod} ->
  81. ok;
  82. {ok, _Mod, []} ->
  83. ok;
  84. {ok, _Mod, Ws} ->
  85. io:format("Warning: ~p~n", [format_warnings(File, Ws)]);
  86. {error, Es, Ws} ->
  87. io:format("~s ~s~n", [format_errors(File, Es), format_warnings(File, Ws)]),
  88. halt(1)
  89. end.
  90. bootstrap_rebar3() ->
  91. filelib:ensure_dir("_build/default/lib/rebar/ebin/dummy.beam"),
  92. file:make_symlink(filename:absname("src"), filename:absname("_build/default/lib/rebar/src")),
  93. Sources = filelib:wildcard("src/*.erl"),
  94. [compile:file(X, [{outdir, "_build/default/lib/rebar/ebin/"}]) || X <- Sources],
  95. code:add_patha(filename:absname("_build/default/lib/rebar/ebin")).
  96. setup_env() ->
  97. %% We don't need or want erlydtl or relx providers loaded yet
  98. application:load(rebar),
  99. {ok, Providers} = application:get_env(rebar, providers),
  100. Providers1 = Providers -- [rebar_prv_erlydtl_compiler,
  101. rebar_prv_release,
  102. rebar_prv_tar],
  103. application:set_env(rebar, providers, Providers1).
  104. reset_env() ->
  105. %% Reset the env so we get all providers and can build erlydtl files
  106. application:unset_env(rebar, providers),
  107. application:unload(rebar),
  108. application:load(rebar).
  109. write_windows_scripts() ->
  110. CmdScript=
  111. "@echo off\r\n"
  112. "setlocal\r\n"
  113. "set rebarscript=%~f0\r\n"
  114. "escript.exe \"%rebarscript:.cmd=%\" %*\r\n",
  115. ok = file:write_file("rebar3.cmd", CmdScript).
  116. get_deps() ->
  117. case file:consult("rebar.lock") of
  118. {ok, [Deps]} ->
  119. [{binary_to_atom(Name, utf8), "", Source} || {Name, Source, _Level} <- Deps];
  120. _ ->
  121. {ok, Config} = file:consult("rebar.config"),
  122. proplists:get_value(deps, Config)
  123. end.
  124. format_errors(Source, Errors) ->
  125. format_errors(Source, "", Errors).
  126. format_warnings(Source, Warnings) ->
  127. format_warnings(Source, Warnings, []).
  128. format_warnings(Source, Warnings, Opts) ->
  129. Prefix = case lists:member(warnings_as_errors, Opts) of
  130. true -> "";
  131. false -> "Warning: "
  132. end,
  133. format_errors(Source, Prefix, Warnings).
  134. format_errors(_MainSource, Extra, Errors) ->
  135. [begin
  136. [format_error(Source, Extra, Desc) || Desc <- Descs]
  137. end
  138. || {Source, Descs} <- Errors].
  139. format_error(AbsSource, Extra, {{Line, Column}, Mod, Desc}) ->
  140. ErrorDesc = Mod:format_error(Desc),
  141. io_lib:format("~s:~w:~w: ~s~s~n", [AbsSource, Line, Column, Extra, ErrorDesc]);
  142. format_error(AbsSource, Extra, {Line, Mod, Desc}) ->
  143. ErrorDesc = Mod:format_error(Desc),
  144. io_lib:format("~s:~w: ~s~s~n", [AbsSource, Line, Extra, ErrorDesc]);
  145. format_error(AbsSource, Extra, {Mod, Desc}) ->
  146. ErrorDesc = Mod:format_error(Desc),
  147. io_lib:format("~s: ~s~s~n", [AbsSource, Extra, ErrorDesc]).