diff options
-rw-r--r-- | .hgignore | 1 | ||||
-rwxr-xr-x | bootstrap | 3 | ||||
-rw-r--r-- | include/rebar.hrl | 2 | ||||
-rw-r--r-- | priv/templates/simplefsm.erl | 55 | ||||
-rw-r--r-- | priv/templates/simplefsm.template | 2 | ||||
-rw-r--r-- | priv/templates/simplemod.erl | 10 | ||||
-rw-r--r-- | priv/templates/simplemod.template | 3 | ||||
-rw-r--r-- | priv/templates/simplemod_tests.erl | 3 | ||||
-rw-r--r-- | priv/templates/simplesrv.erl | 49 | ||||
-rw-r--r-- | priv/templates/simplesrv.template | 2 | ||||
-rw-r--r-- | src/rebar_core.erl | 2 | ||||
-rw-r--r-- | src/rebar_dialyzer.erl | 43 | ||||
-rw-r--r-- | src/rebar_erlc_compiler.erl | 52 | ||||
-rw-r--r-- | src/rebar_eunit.erl | 64 | ||||
-rw-r--r-- | src/rebar_otp_app.erl | 11 | ||||
-rw-r--r-- | src/rebar_port_compiler.erl | 4 | ||||
-rw-r--r-- | src/rebar_utils.erl | 22 |
17 files changed, 268 insertions, 60 deletions
@@ -2,3 +2,4 @@ ^rebar$ .~ \.orig +\.swp @@ -1,5 +1,6 @@ #!/usr/bin/env escript -%% -*- erlang -*- +%% -*- tab-width: 4;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 diff --git a/include/rebar.hrl b/include/rebar.hrl index ad3e2e0..4d591c9 100644 --- a/include/rebar.hrl +++ b/include/rebar.hrl @@ -5,7 +5,7 @@ -define(FAIL, throw({error, failed})). --define(ABORT(Str, Args), ?ERROR(Str, Args), halt(1)). +-define(ABORT(Str, Args), ?ERROR(Str, Args), init:stop(1)). -define(CONSOLE(Str, Args), io:format(Str, Args)). diff --git a/priv/templates/simplefsm.erl b/priv/templates/simplefsm.erl new file mode 100644 index 0000000..039532c --- /dev/null +++ b/priv/templates/simplefsm.erl @@ -0,0 +1,55 @@ +-module({{fsmid}}). +-behaviour(gen_fsm). +-define(SERVER, ?MODULE). + +%% ------------------------------------------------------------------ +%% API Function Exports +%% ------------------------------------------------------------------ + +-export([start_link/0]). + +%% ------------------------------------------------------------------ +%% gen_fsm Function Exports +%% ------------------------------------------------------------------ + +-export([init/1, state_name/2, state_name/3, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). + +%% ------------------------------------------------------------------ +%% API Function Definitions +%% ------------------------------------------------------------------ + +start_link() -> + gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], []). + +%% ------------------------------------------------------------------ +%% gen_fsm Function Definitions +%% ------------------------------------------------------------------ + +init(_Args) -> + {ok, initial_state_name, initial_state}. + +state_name(_Event, State) -> + {next_state, state_name, State}. + +state_name(_Event, _From, State) -> + {reply, ok, state_name, State}. + +handle_event(_Event, StateName, State) -> + {next_state, StateName, State}. + +handle_sync_event(_Event, _From, StateName, State) -> + {reply, ok, StateName, State}. + +handle_info(_Info, StateName, State) -> + {next_state, StateName, State}. + +terminate(_Reason, _StateName, _State) -> + ok. + +code_change(_OldVsn, StateName, State, _Extra) -> + {ok, StateName, State}. + +%% ------------------------------------------------------------------ +%% Internal Function Definitions +%% ------------------------------------------------------------------ + diff --git a/priv/templates/simplefsm.template b/priv/templates/simplefsm.template new file mode 100644 index 0000000..edb6f56 --- /dev/null +++ b/priv/templates/simplefsm.template @@ -0,0 +1,2 @@ +{variables, [{fsmid, "myfsm"}]}. +{file, "simplefsm.erl", "src/{{fsmid}}.erl"}. diff --git a/priv/templates/simplemod.erl b/priv/templates/simplemod.erl new file mode 100644 index 0000000..2baff59 --- /dev/null +++ b/priv/templates/simplemod.erl @@ -0,0 +1,10 @@ +-module({{modid}}). + +-export([my_func/0]). + +-ifdef(TEST). +-compile(export_all). +-endif. + +my_func() -> + ok. diff --git a/priv/templates/simplemod.template b/priv/templates/simplemod.template new file mode 100644 index 0000000..1de8cd0 --- /dev/null +++ b/priv/templates/simplemod.template @@ -0,0 +1,3 @@ +{variables, [{modid, "mymod"}]}. +{file, "simplemod.erl", "src/{{modid}}.erl"}. +{file, "simplemod_tests.erl", "test/{{modid}}_tests.erl"}. diff --git a/priv/templates/simplemod_tests.erl b/priv/templates/simplemod_tests.erl new file mode 100644 index 0000000..c5ca0bb --- /dev/null +++ b/priv/templates/simplemod_tests.erl @@ -0,0 +1,3 @@ +-module({{modid}}_tests). +-include_lib("eunit/include/eunit.hrl"). + diff --git a/priv/templates/simplesrv.erl b/priv/templates/simplesrv.erl new file mode 100644 index 0000000..8db932e --- /dev/null +++ b/priv/templates/simplesrv.erl @@ -0,0 +1,49 @@ +-module({{srvid}}). +-behaviour(gen_server). +-define(SERVER, ?MODULE). + +%% ------------------------------------------------------------------ +%% API Function Exports +%% ------------------------------------------------------------------ + +-export([start_link/0]). + +%% ------------------------------------------------------------------ +%% gen_server Function Exports +%% ------------------------------------------------------------------ + +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). + +%% ------------------------------------------------------------------ +%% API Function Definitions +%% ------------------------------------------------------------------ + +start_link() -> + gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). + +%% ------------------------------------------------------------------ +%% gen_server Function Definitions +%% ------------------------------------------------------------------ + +init(Args) -> + {ok, Args}. + +handle_call(_Request, _From, State) -> + {noreply, ok, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%% ------------------------------------------------------------------ +%% Internal Function Definitions +%% ------------------------------------------------------------------ + diff --git a/priv/templates/simplesrv.template b/priv/templates/simplesrv.template new file mode 100644 index 0000000..e72dd25 --- /dev/null +++ b/priv/templates/simplesrv.template @@ -0,0 +1,2 @@ +{variables, [{srvid, "myserver"}]}. +{file, "simplesrv.erl", "src/{{srvid}}.erl"}. diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 68391e7..1cefe84 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -188,7 +188,7 @@ process_dir(Dir, ParentConfig, Commands) -> %% Get the list of modules for "any dir". This is a catch-all list of modules %% that are processed in addion to modules associated with this directory - %5 type. These any_dir modules are processed FIRST. + %% type. These any_dir modules are processed FIRST. {ok, AnyDirModules} = application:get_env(rebar, any_dir_modules), Modules = AnyDirModules ++ DirModules, diff --git a/src/rebar_dialyzer.erl b/src/rebar_dialyzer.erl index c725e48..35bb201 100644 --- a/src/rebar_dialyzer.erl +++ b/src/rebar_dialyzer.erl @@ -28,7 +28,7 @@ %% @doc rebar_dialyzer supports the following commands: %% <ul> %% <li>analyze (essentially "dialyzer -r ebin")</li> -%% <li>build_plt (essentially "dialyzer --build_plt -r &rt;stdlib_lib< &rt;kernel_lib< &rt;mnesia_lib<")</li> +%% <li>build_plt (essentially "dialyzer --build_plt -r <app_dirs>")</li> %% <li>check_plt (essentially "dialyzer --check_plt")</li> %% </ul> %% A single option <code>plt</code> can be presented in the <code>dialyzer_opts</code> @@ -59,8 +59,8 @@ %% @doc Perform static analysis on the contents of the ebin directory. %% @spec analyze(Config::#config{}, File::string()) -> ok. -spec(analyze(Config::#config{}, File::string()) -> ok). -analyze(Config, _File) -> - Plt = plt_path(Config), +analyze(Config, File) -> + Plt = plt_path(Config, File), case dialyzer:plt_info(Plt) of {ok, _} -> try dialyzer:run([{files_rec, ["ebin"]}, {init_plt, Plt}]) of @@ -82,17 +82,14 @@ analyze(Config, _File) -> %% @doc Build the PLT. %% @spec build_plt(Config::#config{}, File::string()) -> ok -spec(build_plt(Config::#config{}, File::string()) -> ok). -build_plt(Config, _File) -> - Plt = plt_path(Config), +build_plt(Config, File) -> + Plt = plt_path(Config, File), - %% This is the recommended minimal PLT for OTP - %% (see http://www.erlang.org/doc/apps/dialyzer/dialyzer_chapter.html#id2256857). + {ok, _AppName, AppData} = rebar_app_utils:load_app_file(File), + Apps = proplists:get_value(applications, AppData), + Warnings = dialyzer:run([{analysis_type, plt_build}, - {files_rec, [ - filename:join(code:lib_dir(stdlib), "ebin"), - filename:join(code:lib_dir(kernel), "ebin"), - filename:join(code:lib_dir(mnesia), "ebin") - ]}, + {files_rec, app_dirs(Apps)}, {output_plt, Plt}]), case Warnings of [] -> @@ -105,8 +102,8 @@ build_plt(Config, _File) -> %% @doc Check whether the PLT is up-to-date (rebuilding it if not). %% @spec check_plt(Config::#config{}, File::string()) -> ok -spec(check_plt(Config::#config{}, File::string()) -> ok). -check_plt(Config, _File) -> - Plt = plt_path(Config), +check_plt(Config, File) -> + Plt = plt_path(Config, File), try dialyzer:run([{analysis_type, plt_check}, {init_plt, Plt}]) of [] -> ?CONSOLE("The PLT ~s is up-to-date~n", [Plt]); @@ -123,8 +120,15 @@ check_plt(Config, _File) -> %% Internal functions %% =================================================================== +%% @doc Obtain the library paths for the supplied applications. +%% @spec app_dirs(Apps::[atom()]) -> [string()] +-spec(app_dirs(Apps::[atom()]) -> [string()]). +app_dirs(Apps) -> + [filename:join(Path, "ebin") || + Path <- lists:map(fun(App) -> code:lib_dir(App) end, Apps), erlang:is_list(Path)]. + %% @doc Render the warnings on the console. -%% @spec output_warnings(Warnings::[warning()]) -> void() +%% @spec output_warnings(Warnings::[warning()]) -> none() -spec(output_warnings(Warnings::[warning()]) -> none()). output_warnings(Warnings) -> lists:foreach(fun(Warning) -> @@ -133,13 +137,14 @@ output_warnings(Warnings) -> %% @doc If the plt option is present in rebar.config return its value, otherwise %% return $HOME/.dialyzer_plt. -%% @spec plt_path(Config::#config{}) -> string() --spec(plt_path(Config::#config{}) -> string()). -plt_path(Config) -> +%% @spec plt_path(Config::#config{}, File::string()) -> string() +-spec(plt_path(Config::#config{}, File::string()) -> string()). +plt_path(Config, File) -> + {ok, AppName, _AppData} = rebar_app_utils:load_app_file(File), DialyzerOpts = rebar_config:get(Config, dialyzer_opts, []), case proplists:get_value(plt, DialyzerOpts) of undefined -> - filename:join(os:getenv("HOME"), ".dialyzer_plt"); + filename:join(os:getenv("HOME"), "." ++ atom_to_list(AppName) ++ "_dialyzer_plt"); Plt -> Plt end. diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 04878c3..c41b96d 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -4,7 +4,7 @@ %% %% rebar: Erlang Build Tools %% -%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com) +%% Copyright (c) 2009, 2010 Dave Smith (dizzyd@dizzyd.com) %% %% Permission is hereby granted, free of charge, to any person obtaining a copy %% of this software and associated documentation files (the "Software"), to deal @@ -38,12 +38,14 @@ %% Public API %% =================================================================== +-spec compile(Config::#config{}, AppFile::string()) -> 'ok'. compile(Config, _AppFile) -> doterl_compile(Config, "ebin"), rebar_base_compiler:run(Config, rebar_config:get_list(Config, mib_first_files, []), "mibs", ".mib", "priv/mibs", ".bin", fun compile_mib/3). +-spec clean(Config::#config{}, AppFile::string()) -> 'ok'. clean(_Config, _AppFile) -> %% TODO: This would be more portable if it used Erlang to traverse %% the dir structure and delete each file; however it would also @@ -64,26 +66,33 @@ clean(_Config, _AppFile) -> %% .erl Compilation API (externally used by only eunit) %% =================================================================== +-spec doterl_compile(Config::#config{}, OutDir::string()) -> 'ok'. doterl_compile(Config, OutDir) -> doterl_compile(Config, OutDir, []). doterl_compile(Config, OutDir, MoreSources) -> FirstErls = rebar_config:get_list(Config, erl_first_files, []), - RestErls = [Source || Source <- rebar_utils:find_files("src", ".*\\.erl\$") ++ MoreSources, + ErlOpts = rebar_config:get(Config, erl_opts, []), + %% Support the src_dirs option allowing multiple directories to + %% contain erlang source. This might be used, for example, should eunit tests be + %% separated from the core application source. + SrcDirs = src_dirs(proplists:append_values(src_dirs, ErlOpts)), + RestErls = [Source || Source <- gather_src(SrcDirs, []) ++ MoreSources, lists:member(Source, FirstErls) == false], rebar_base_compiler:run(Config, FirstErls, RestErls, fun(S, C) -> internal_erl_compile(S, C, OutDir) end). - %% =================================================================== %% Internal functions %% =================================================================== +-spec include_path(Source::string(), Config::#config{}) -> [string()]. include_path(Source, Config) -> ErlOpts = rebar_config:get(Config, erl_opts, []), [filename:dirname(Source)] ++ proplists:get_all_values(i, ErlOpts). +-spec inspect(Source::string(), IncludePath::[string()]) -> {string(), [string()]}. inspect(Source, IncludePath) -> ModuleDefault = filename:basename(Source, ".erl"), case epp:open(Source, IncludePath) of @@ -94,15 +103,23 @@ inspect(Source, IncludePath) -> {ModuleDefault, []} end. +-spec inspect_epp(Epp::pid(), Module::string(), Includes::[string()]) -> {string(), [string()]}. inspect_epp(Epp, Module, Includes) -> case epp:parse_erl_form(Epp) of - {ok, {attribute, _, module, ActualModule}} when is_list(ActualModule) -> - %% If the module name includes package info, we get a list of atoms... - case is_list(ActualModule) of - true -> + {ok, {attribute, _, module, ModInfo}} -> + case ModInfo of + %% Typical module name, single atom + ActualModule when is_atom(ActualModule) -> + ActualModuleStr = atom_to_list(ActualModule); + %% Packag-ized module name, list of atoms + ActualModule when is_list(ActualModule) -> ActualModuleStr = string:join([atom_to_list(P) || P <- ActualModule], "."); - false -> - ActualModuleStr = atom_to_list(ActualModule) + %% Parameterized module name, single atom + {ActualModule, _} when is_atom(ActualModule) -> + ActualModuleStr = atom_to_list(ActualModule); + %% Parameterized and packagized module name, list of atoms + {ActualModule, _} when is_list(ActualModule) -> + ActualModuleStr = string:join([atom_to_list(P) || P <- ActualModule], ".") end, inspect_epp(Epp, ActualModuleStr, Includes); {ok, {attribute, 1, file, {Module, 1}}} -> @@ -116,12 +133,13 @@ inspect_epp(Epp, Module, Includes) -> inspect_epp(Epp, Module, Includes) end. +-spec needs_compile(Source::string(), Target::string(), Hrls::[string()]) -> boolean(). needs_compile(Source, Target, Hrls) -> TargetLastMod = filelib:last_modified(Target), lists:any(fun(I) -> TargetLastMod < filelib:last_modified(I) end, [Source] ++ Hrls). - +-spec internal_erl_compile(Source::string(), Config::#config{}, Outdir::string()) -> 'ok' | 'skipped'. internal_erl_compile(Source, Config, Outdir) -> %% Determine the target name and includes list by inspecting the source file {Module, Hrls} = inspect(Source, include_path(Source, Config)), @@ -154,6 +172,7 @@ internal_erl_compile(Source, Config, Outdir) -> skipped end. +-spec compile_mib(Source::string(), Target::string(), Config::#config{}) -> 'ok'. compile_mib(Source, Target, Config) -> ok = rebar_utils:ensure_dir(Target), Opts = [{outdir, "priv/mibs"}, {i, ["priv/mibs"]}] ++ @@ -165,9 +184,22 @@ compile_mib(Source, Target, Config) -> ?FAIL end. +gather_src([], Srcs) -> + Srcs; +gather_src([Dir|Rest], Srcs) -> + gather_src(Rest, Srcs ++ rebar_utils:find_files(Dir, ".*\\.erl\$")). + +-spec src_dirs(SrcDirs::[string()]) -> [string()]. +src_dirs([]) -> + ["src"]; +src_dirs(SrcDirs) -> + SrcDirs ++ src_dirs([]). + +-spec dirs(Dir::string()) -> [string()]. dirs(Dir) -> [F || F <- filelib:wildcard(filename:join([Dir, "*"])), filelib:is_dir(F)]. +-spec delete_dir(Dir::string(), Subdirs::[string()]) -> 'ok' | {'error', atom()}. delete_dir(Dir, []) -> file:del_dir(Dir); delete_dir(Dir, Subdirs) -> diff --git a/src/rebar_eunit.erl b/src/rebar_eunit.erl index 6ef7a25..4c280e9 100644 --- a/src/rebar_eunit.erl +++ b/src/rebar_eunit.erl @@ -4,7 +4,7 @@ %% %% rebar: Erlang Build Tools %% -%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com) +%% Copyright (c) 2009, 2010 Dave Smith (dizzyd@dizzyd.com) %% %% Permission is hereby granted, free of charge, to any person obtaining a copy %% of this software and associated documentation files (the "Software"), to deal @@ -24,14 +24,21 @@ %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN %% THE SOFTWARE. %% ------------------------------------------------------------------- -%% -%% Targets: -%% eunit - runs eunit tests -%% clean - remove .eunit directory -%% -%% Global options: -%% verbose=1 - show extra output from the eunit test -%% suite="foo"" - runs test/foo_tests.erl +%% @author Dave Smith <dizzyd@dizzyd.com> +%% @doc rebar_eunit supports the following commands: +%% <ul> +%% <li>eunit - runs eunit tests</li> +%% <li>clean - remove .eunit directory</li> +%% </ul> +%% The following Global options are supported: +%% <ul> +%% <li>verbose=1 - show extra output from the eunit test</li> +%% <li>suite="foo"" - runs test/foo_tests.erl</li> +%% </ul> +%% Additionally, for projects that have separate folders for the core +%% implementation, and for the unit tests, then the following <code>rebar.config</code> +%% option can be provided: <code>{eunit_compile_opts, [{src_dirs, ["dir"]}]}.</code>. +%% @copyright 2009, 2010 Dave Smith %% ------------------------------------------------------------------- -module(rebar_eunit). @@ -51,9 +58,13 @@ eunit(Config, _File) -> %% Make sure ?EUNIT_DIR/ directory exists (tack on dummy module) ok = filelib:ensure_dir(?EUNIT_DIR ++ "/foo"), + %% grab all the test modules for inclusion in the compile stage + TestErls = rebar_utils:find_files("test", ".*\\.erl\$"), + %% Compile erlang code to ?EUNIT_DIR, using a tweaked config - %% with appropriate defines for eunit - rebar_erlc_compiler:doterl_compile(eunit_config(Config), ?EUNIT_DIR), + %% with appropriate defines for eunit, and include all the test modules + %% as well. + rebar_erlc_compiler:doterl_compile(eunit_config(Config), ?EUNIT_DIR, TestErls), %% Build a list of all the .beams in ?EUNIT_DIR -- use this for cover %% and eunit testing. Normally you can just tell cover and/or eunit to @@ -62,8 +73,35 @@ eunit(Config, _File) -> %% we do it by hand. :( %% %% TODO: Not currently compatible with package modules - Modules = [list_to_atom(filename:basename(N, ".beam")) || - N <- filelib:wildcard("*.beam", ?EUNIT_DIR)], + Beams = [filename:basename(N, ".beam") || N <- rebar_utils:beams(?EUNIT_DIR)], + + %% Grab two lists of test and non-test beam files + {TestBeams, ModuleBeams} = lists:partition(fun(B) -> + lists:suffix("_tests", B) end, Beams), + + case rebar_config:get_global(suite, undefined) of + undefined -> + %% no suite defined, so include all modules + RealModules = ModuleBeams, + + %% exclude any test modules that have a matching module + TestModules = [T || T <- TestBeams, + lists:member(string:left(T, length(T) - 6), RealModules) == false]; + SuiteName -> + %% suite defined, so only specify the module that relates to the + %% suite (if any) + RealModules = [M || M <- ModuleBeams, SuiteName =:= M], + + %% only include the test suite if the main module doesn't exist + TestModules = case length(RealModules) of + 0 -> [T || T <- TestBeams, T =:= SuiteName ++ "_tests"]; + _ -> [] + end + end, + + %% combine the modules and associated test modules into the resulting list + %% of modules to run tests on. + Modules = [list_to_atom(M) || M <- RealModules ++ TestModules], %% TODO: If there are other wildcards specified in eunit_sources, compile them diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl index 136c5cb..f20ce0c 100644 --- a/src/rebar_otp_app.erl +++ b/src/rebar_otp_app.erl @@ -131,7 +131,7 @@ validate_modules(AppName, undefined) -> validate_modules(AppName, Mods) -> %% Construct two sets -- one for the actual .beam files in ebin/ and one for the modules %% listed in the .app file - EbinSet = ordsets:from_list([beam_to_mod(N) || N <- beams()]), + EbinSet = ordsets:from_list([rebar_utils:beam_to_mod("ebin", N) || N <- rebar_utils:beams("ebin")]), ModSet = ordsets:from_list(Mods), %% Identify .beam files listed in the .app, but not present in ebin/ @@ -155,12 +155,3 @@ validate_modules(AppName, Mods) -> [AppName, Msg2]), ?FAIL end. - -beam_to_mod(Filename) -> - ["ebin" | Rest] = filename:split(Filename), - list_to_atom(filename:basename(string:join(Rest, "."), ".beam")). - -beams() -> - filelib:fold_files("ebin", ".*\.beam\$", true, - fun(F, Acc) -> [F | Acc] end, []). - diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl index a347cb7..b08a046 100644 --- a/src/rebar_port_compiler.erl +++ b/src/rebar_port_compiler.erl @@ -253,7 +253,9 @@ default_env() -> " -I", filename:join(erts_dir(), include), " "])}, {"DRIVER_LDFLAGS", lists:concat([" -L", code:lib_dir(erl_interface, lib), - " -lerl_interface -lei"])}]. + " -lerl_interface -lei"])}, + {"ERLANG_ARCH", integer_to_list(8 * erlang:system_info(wordsize))}, + {"ERLANG_TARGET", rebar_utils:get_arch()}]. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 5f1612c..1e99caa 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -4,7 +4,7 @@ %% %% rebar: Erlang Build Tools %% -%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com) +%% Copyright (c) 2009, 2010 Dave Smith (dizzyd@dizzyd.com) %% %% Permission is hereby granted, free of charge, to any person obtaining a copy %% of this software and associated documentation files (the "Software"), to deal @@ -28,12 +28,14 @@ -export([get_cwd/0, is_arch/1, + get_arch/0, get_os/0, sh/2, sh/3, sh_failfast/2, find_files/2, now_str/0, - ensure_dir/1]). + ensure_dir/1, + beam_to_mod/2, beams/1]). -include("rebar.hrl"). @@ -47,14 +49,17 @@ get_cwd() -> is_arch(ArchRegex) -> - Arch = erlang:system_info(system_architecture), - case re:run(Arch, ArchRegex, [{capture, none}]) of + case re:run(get_arch(), ArchRegex, [{capture, none}]) of match -> true; nomatch -> false end. +get_arch() -> + Words = integer_to_list(8 * erlang:system_info(wordsize)), + erlang:system_info(system_architecture) ++ "-" ++ Words. + get_os() -> Arch = erlang:system_info(system_architecture), case match_first([{"linux", linux}, {"darwin", darwin}], Arch) of @@ -132,3 +137,12 @@ sh_loop(Port) -> {Port, {exit_status, Rc}} -> {error, Rc} end. + +beam_to_mod(Dir, Filename) -> + [Dir | Rest] = filename:split(Filename), + list_to_atom(filename:basename(string:join(Rest, "."), ".beam")). + +beams(Dir) -> + filelib:fold_files(Dir, ".*\.beam\$", true, + fun(F, Acc) -> [F | Acc] end, []). + |