| #!/usr/bin/env escript |
| %% -*- erlang -*- |
| |
| main(Args) -> |
| %% Get a string repr of build time |
| Built = build_time(), |
| |
| %% Check for force=1 flag to force a rebuild |
| case lists:member("force=1", Args) of |
| true -> |
| [] = os:cmd("rm -rf ebin/*.beam"), |
| ok; |
| false -> |
| ok |
| end, |
| |
| %% Compile all src/*.erl to ebin |
| case make:files(filelib:wildcard("src/*.erl"), [{outdir, "ebin"}, {i, "include"}, |
| {d, 'BUILD_TIME', Built}]) 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 to do proper .app validation and such |
| rebar:main(["compile"] ++ Args), |
| |
| %% Construct the archive of everything in ebin/ dir -- put it on the |
| %% top-level of the zip file so that code loading works properly. |
| Files = filelib:wildcard("*", "ebin"), |
| case zip:create("mem", Files, [{cwd, "ebin"}, memory]) of |
| {ok, {"mem", ZipBin}} -> |
| %% Archive was successfully created. Prefix that binary with our |
| %% header and write to "rebar" file |
| Script = <<"#!/usr/bin/env escript\n", ZipBin/binary>>, |
| case file:write_file("rebar", Script) of |
| ok -> |
| ok; |
| {error, WriteError} -> |
| io:format("Failed to write rebar script: ~p\n", [WriteError]), |
| halt(1) |
| end; |
| {error, ZipError} -> |
| io:format("Failed to construct rebar script archive: ~p\n", [ZipError]), |
| halt(1) |
| end, |
| |
| %% Finally, update executable perms for our script |
| [] = os:cmd("chmod u+x rebar"), |
| |
| %% 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"). |
| |
| |
| 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])). |
| |
| |