| #!/usr/bin/env escript |
| %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- |
| %% ex: ft=erlang ts=4 sw=4 et |
| |
| main(Args) -> |
| %% Get a string repr of build time |
| Built = build_time(), |
| |
| %% Get a string repr of first matching VCS changeset |
| VcsInfo = vcs_info([{hg, ".hg", "hg identify -i", "hg status"}, |
| {git, ".git", "git describe --always --tags", |
| "git status -s"}]), |
| |
| %% Check for force=1 flag to force a rebuild |
| case lists:member("force=1", Args) of |
| true -> |
| rm("ebin/*.beam"); |
| false -> |
| rm("ebin/rebar.beam") |
| end, |
| |
| %% Add check for debug flag |
| DebugFlag = case lists:member("debug", Args) of |
| true -> debug_info; |
| false -> undefined |
| end, |
| |
| %% Extract the system info of the version of OTP we use to compile rebar |
| OtpInfo = string:strip(erlang:system_info(otp_release), both, $\n), |
| |
| %% Compile all src/*.erl to ebin |
| case make:files(filelib:wildcard("src/*.erl"), |
| [{outdir, "ebin"}, {i, "include"}, |
| DebugFlag, |
| {d, 'BUILD_TIME', Built}, |
| {d, 'VCS_INFO', VcsInfo}, |
| {d, 'OTP_INFO', OtpInfo}]) of |
| up_to_date -> |
| ok; |
| error -> |
| io:format("Failed to compile rebar files!\n"), |
| halt(1) |
| end, |
| |
| %% Make sure file:consult can parse the .app file |
| case file:consult("ebin/rebar.app") of |
| {ok, _} -> |
| ok; |
| {error, Reason} -> |
| io:format("Invalid syntax in ebin/rebar.app: ~p\n", [Reason]), |
| halt(1) |
| end, |
| |
| %% Add ebin/ to our path |
| true = code:add_path("ebin"), |
| |
| %% Run rebar compile to do proper .app validation etc. |
| %% and rebar escriptize to create the rebar script |
| rebar:main(["compile", "escriptize"] ++ Args), |
| |
| %% Finally, update executable perms for our script on *nix, |
| %% or write out script files on win32. |
| case os:type() of |
| {unix,_} -> |
| [] = os:cmd("chmod u+x rebar"), |
| ok; |
| {win32,_} -> |
| write_windows_scripts(), |
| ok; |
| _ -> |
| ok |
| end, |
| |
| %% Add a helpful message |
| io:format("Congratulations! You now have a self-contained script called" |
| " \"rebar\" in\n" |
| "your current working directory. " |
| "Place this script anywhere in your path\n" |
| "and you can use rebar to build OTP-compliant apps.\n"). |
| |
| rm(Path) -> |
| NativePath = filename:nativename(Path), |
| Cmd = case os:type() of |
| {unix,_} -> "rm -f "; |
| {win32,_} -> "del /q " |
| end, |
| [] = os:cmd(Cmd ++ NativePath), |
| ok. |
| |
| build_time() -> |
| {{Y, M, D}, {H, Min, S}} = calendar:now_to_universal_time(now()), |
| lists:flatten(io_lib:format("~4..0w~2..0w~2..0w_~2..0w~2..0w~2..0w", |
| [Y, M, D, H, Min, S])). |
| |
| vcs_info([]) -> |
| "No VCS info available."; |
| vcs_info([{Id, Dir, VsnCmd, StatusCmd} | Rest]) -> |
| case filelib:is_dir(Dir) of |
| true -> |
| Vsn = string:strip(os:cmd(VsnCmd), both, $\n), |
| Status = case string:strip(os:cmd(StatusCmd), both, $\n) of |
| [] -> |
| ""; |
| _ -> |
| "-dirty" |
| end, |
| lists:concat([Id, " ", Vsn, Status]); |
| false -> |
| vcs_info(Rest) |
| end. |
| |
| write_windows_scripts() -> |
| CmdScript= |
| "@echo off\r\n" |
| "setlocal\r\n" |
| "set rebarscript=%~f0\r\n" |
| "escript.exe \"%rebarscript:.cmd=%\" %*\r\n", |
| ok = file:write_file("rebar.cmd", CmdScript). |