Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

148 řádky
4.7 KiB

před 14 roky
před 14 roky
před 15 roky
před 14 roky
před 15 roky
před 14 roky
  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. case lists:member("--help", Args) of
  6. true ->
  7. usage(),
  8. halt(0);
  9. false ->
  10. ok
  11. end,
  12. %% Get a string repr of build time
  13. Built = build_time(),
  14. %% Get a string repr of first matching VCS changeset
  15. VcsInfo = vcs_info([{hg, ".hg", "hg identify -i", "hg status"},
  16. {git, ".git", "git describe --always --tags",
  17. "git status -s"}]),
  18. %% Check for force=1 flag to force a rebuild
  19. case lists:member("force=1", Args) of
  20. true ->
  21. rm("ebin/*.beam");
  22. false ->
  23. rm("ebin/rebar.beam")
  24. end,
  25. %% Add check for debug flag
  26. DebugFlag = case lists:member("debug", Args) of
  27. true -> debug_info;
  28. false -> undefined
  29. end,
  30. %% Extract the system info of the version of OTP we use to compile rebar
  31. OtpInfo = string:strip(erlang:system_info(otp_release), both, $\n),
  32. %% Types dict:dict() and digraph:digraph() have been introduced in Erlang 17.
  33. %% At the same time, their counterparts dict() and digraph() are to be deprecated
  34. %% in Erlang 18. namespaced_types option is used to select proper type name
  35. %% depending of the OTP version used.
  36. NamespacedTypes = case is_otp(OtpInfo, "^[0-9]+") of
  37. true -> {d, namespaced_types};
  38. false -> undefined
  39. end,
  40. %% Compile all src/*.erl to ebin
  41. case make:files(filelib:wildcard("src/*.erl"),
  42. [{outdir, "ebin"}, {i, "include"},
  43. DebugFlag,
  44. NamespacedTypes,
  45. {d, 'BUILD_TIME', Built},
  46. {d, 'VCS_INFO', VcsInfo},
  47. {d, 'OTP_INFO', OtpInfo}]) of
  48. up_to_date ->
  49. ok;
  50. error ->
  51. io:format("Failed to compile rebar files!\n"),
  52. halt(1)
  53. end,
  54. %% Make sure file:consult can parse the .app file
  55. case file:consult("ebin/rebar.app") of
  56. {ok, _} ->
  57. ok;
  58. {error, Reason} ->
  59. io:format("Invalid syntax in ebin/rebar.app: ~p\n", [Reason]),
  60. halt(1)
  61. end,
  62. %% Add ebin/ to our path
  63. true = code:add_path("ebin"),
  64. %% Run rebar compile to do proper .app validation etc.
  65. %% and rebar escriptize to create the rebar script
  66. RebarArgs = Args -- ["debug"], %% Avoid trying to run 'debug' command
  67. rebar:main(["compile", "escriptize"] ++ RebarArgs),
  68. %% Finally, update executable perms for our script on *nix,
  69. %% or write out script files on win32.
  70. case os:type() of
  71. {unix,_} ->
  72. [] = os:cmd("chmod u+x rebar"),
  73. ok;
  74. {win32,_} ->
  75. write_windows_scripts(),
  76. ok;
  77. _ ->
  78. ok
  79. end,
  80. %% Add a helpful message
  81. io:format("Congratulations! You now have a self-contained script called"
  82. " \"rebar\" in\n"
  83. "your current working directory. "
  84. "Place this script anywhere in your path\n"
  85. "and you can use rebar to build OTP-compliant apps.\n").
  86. usage() ->
  87. io:format("Usage: bootstrap [OPTION]...~n"),
  88. io:format(" force=1\t unconditional build~n"),
  89. io:format(" debug\t add debug information~n").
  90. is_otp(OtpInfo, Regex) ->
  91. case re:run(OtpInfo, Regex, [{capture, none}]) of
  92. match -> true;
  93. nomatch -> false
  94. end.
  95. rm(Path) ->
  96. NativePath = filename:nativename(Path),
  97. Cmd = case os:type() of
  98. {unix,_} -> "rm -f ";
  99. {win32,_} -> "del /q "
  100. end,
  101. [] = os:cmd(Cmd ++ NativePath),
  102. ok.
  103. build_time() ->
  104. {{Y, M, D}, {H, Min, S}} = calendar:now_to_universal_time(now()),
  105. lists:flatten(io_lib:format("~4..0w~2..0w~2..0w_~2..0w~2..0w~2..0w",
  106. [Y, M, D, H, Min, S])).
  107. vcs_info([]) ->
  108. "No VCS info available.";
  109. vcs_info([{Id, Dir, VsnCmd, StatusCmd} | Rest]) ->
  110. case filelib:is_dir(Dir) of
  111. true ->
  112. Vsn = string:strip(os:cmd(VsnCmd), both, $\n),
  113. Status = case string:strip(os:cmd(StatusCmd), both, $\n) of
  114. [] ->
  115. "";
  116. _ ->
  117. "-dirty"
  118. end,
  119. lists:concat([Id, " ", Vsn, Status]);
  120. false ->
  121. vcs_info(Rest)
  122. end.
  123. write_windows_scripts() ->
  124. CmdScript=
  125. "@echo off\r\n"
  126. "setlocal\r\n"
  127. "set rebarscript=%~f0\r\n"
  128. "escript.exe \"%rebarscript:.cmd=%\" %*\r\n",
  129. ok = file:write_file("rebar.cmd", CmdScript).