From dfb5af404978fad2cef4c1e6a4c6545217e55cc8 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Fri, 5 Mar 2010 22:56:31 +0100 Subject: [PATCH 1/8] Add forward-compatible escript_foldl function escript:foldl/3 was undocumented and has been replaced with better APIs post-R13B04. The new exported funs are officially documented. --- src/rebar_templater.erl | 7 +++++-- src/rebar_utils.erl | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/rebar_templater.erl b/src/rebar_templater.erl index c4217cd..fd1d813 100644 --- a/src/rebar_templater.erl +++ b/src/rebar_templater.erl @@ -110,8 +110,11 @@ create(_Config, _) -> %% Scan the current escript for available files and cache in pdict. %% cache_escript_files() -> - {ok, Files} = escript:foldl(fun(Name, _, GetBin, Acc) -> [{Name, GetBin()} | Acc] end, - [], rebar_config:get_global(escript, undefined)), + {ok, Files} = rebar_utils:escript_foldl( + fun(Name, _, GetBin, Acc) -> + [{Name, GetBin()} | Acc] + end, + [], rebar_config:get_global(escript, undefined)), erlang:put(escript_files, Files). diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index bfe7bce..4bf089e 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -36,7 +36,8 @@ now_str/0, ensure_dir/1, beam_to_mod/2, beams/1, - abort/2]). + abort/2, + escript_foldl/3]). -include("rebar.hrl"). @@ -111,6 +112,14 @@ abort(String, Args) -> ?ERROR(String, Args), halt(1). +escript_foldl(Fun, Acc, File) -> + case erlang:function_exported(zip, foldl, 3) of + true -> + emulate_escript_foldl(Fun, Acc, File); + false -> + escript:foldl(Fun, Acc, File) + end. + %% ==================================================================== %% Internal functions %% ==================================================================== @@ -144,3 +153,21 @@ beams(Dir) -> filelib:fold_files(Dir, ".*\.beam\$", true, fun(F, Acc) -> [F | Acc] end, []). +emulate_escript_foldl(Fun, Acc, File) -> + case escript:extract(File, [compile_source]) of + {ok, [_Shebang, _Comment, _EmuArgs, Body]} -> + case Body of + {source, BeamCode} -> + GetInfo = fun() -> file:read_file_info(File) end, + GetBin = fun() -> BeamCode end, + {ok, Fun(".", GetInfo, GetBin, Acc)}; + {beam, BeamCode} -> + GetInfo = fun() -> file:read_file_info(File) end, + GetBin = fun() -> BeamCode end, + {ok, Fun(".", GetInfo, GetBin, Acc)}; + {archive, ArchiveBin} -> + zip:foldl(Fun, Acc, {File, ArchiveBin}) + end; + {error, Reason} -> + {error, Reason} + end. From aeabfb6fe93cf2a7d0af5d0b6f05b7cb7b887158 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Sat, 6 Mar 2010 00:04:50 +0100 Subject: [PATCH 2/8] Add escript_foldl/3 TODO Comment what has to be done when the new OTP release is out and the time is right. --- src/rebar_utils.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 4bf089e..0ac6cf1 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -112,6 +112,9 @@ abort(String, Args) -> ?ERROR(String, Args), halt(1). +%% TODO: Rename emulate_escript_foldl to escript_foldl and remove +%% this function when the time is right. escript:foldl/3 was an +%% undocumented exported fun and is going to be removed post-R13B04. escript_foldl(Fun, Acc, File) -> case erlang:function_exported(zip, foldl, 3) of true -> From 218051618fc95cbf0def17d309fe135b57dc0146 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Sat, 6 Mar 2010 13:22:07 +0100 Subject: [PATCH 3/8] Add TODO file A TODO file is always a good idea. --- TODO | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..e464181 --- /dev/null +++ b/TODO @@ -0,0 +1,3 @@ +* ZSH completion script +* rebar option or command to list all available + commands/tasks From ebfb1dc40d3623684234441c96a2a8850316f516 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 8 Mar 2010 21:14:06 +0100 Subject: [PATCH 4/8] Add option to show available commands Implement new option -c/--commands to print available commands and its variables. --- src/rebar_core.erl | 101 ++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 28 deletions(-) diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 7cf0c7a..cd5df50 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -85,32 +85,25 @@ parse_args(Args) -> %% Parse getopt options OptSpecList = option_spec_list(), case getopt:parse(OptSpecList, Args) of - {ok, {_Options, []}} -> - %% no command to run specified - help(), - halt(1); {ok, {Options, NonOptArgs}} -> - case proplists:get_bool(help, Options) of - true -> - %% display help - help(), - halt(0); - false -> - %% Set global variables based on getopt options - set_global_flag(Options, verbose), - set_global_flag(Options, force), - DefJobs = rebar_config:get_jobs(), - case proplists:get_value(jobs, Options, DefJobs) of - DefJobs -> - ok; - Jobs -> - rebar_config:set_global(jobs, Jobs) - end, + %% Check options and maybe halt execution + {ok, continue} = print_help_maybe_halt(Options, NonOptArgs), + + %% Set global variables based on getopt options + set_global_flag(Options, verbose), + set_global_flag(Options, force), + DefJobs = rebar_config:get_jobs(), + case proplists:get_value(jobs, Options, DefJobs) of + DefJobs -> + ok; + Jobs -> + rebar_config:set_global(jobs, Jobs) + end, + + %% Filter all the flags (i.e. strings of form key=value) from the + %% command line arguments. What's left will be the commands to run. + filter_flags(NonOptArgs, []); - %% Filter all the flags (i.e. strings of form key=value) from the - %% command line arguments. What's left will be the commands to run. - filter_flags(NonOptArgs, []) - end; {error, {Reason, Data}} -> ?ERROR("Error: ~s ~p~n~n", [Reason, Data]), help(), @@ -129,6 +122,31 @@ set_global_flag(Options, Flag) -> end, rebar_config:set_global(Flag, Value). +%% +%% print help +%% +print_help_maybe_halt(Options, NonOptArgs) -> + case proplists:get_bool(help, Options) of + true -> + help(), + halt(0); + false -> + case proplists:get_bool(commands, Options) of + true -> + commands(), + halt(0); + false -> + case NonOptArgs of + [] -> + io:format("No command to run specified!~n"), + help(), + halt(1); + _ -> + {ok, continue} + end + end + end. + %% %% print help/usage string %% @@ -139,6 +157,32 @@ help() -> [{"var=value", "rebar global variables (e.g. force=1)"}, {"command", "Command to run (e.g. compile)"}]). +%% +%% print known commands +%% +commands() -> + io:format(<< +"analyze Analyze with Dialyzer~n" +"build_plt Build Dialyzer PLT~n" +"check_plt Check Dialyzer PLT~n" +"~n" +"clean Clean~n" +"compile Compile sources~n" +"~n" +"create template= [var=foo,...] Create skel based on template and vars~n" +"create-app Create simple app skel~n" +"create-node Create simple node skel~n" +"~n" +"generate [dump_spec=0/1] Build release with reltool~n" +"install [target=] Install build into target~n" +"~n" +"eunit [suite=foo] Run eunit [test/foo_tests.erl] tests~n" +"~n" +"int_test [suite=] [case=] Run ct suites in ./int_test~n" +"perf_test [suite=] [case=] Run ct suites in ./perf_test~n" +"test [suite=] [case=] Run ct suites in ./test~n" +>>). + %% %% options accepted via getopt %% @@ -149,10 +193,11 @@ option_spec_list() -> [Jobs]), [ %% {Name, ShortOpt, LongOpt, ArgSpec, HelpMsg} - {help, $h, "help", undefined, "Show the program options"}, - {verbose, $v, "verbose", undefined, "Be verbose about what gets done"}, - {force, $f, "force", undefined, "Force"}, - {jobs, $j, "jobs", integer, JobsHelp} + {help, $h, "help", undefined, "Show the program options"}, + {commands, $c, "commands", undefined, "Show available commands"}, + {verbose, $v, "verbose", undefined, "Be verbose about what gets done"}, + {force, $f, "force", undefined, "Force"}, + {jobs, $j, "jobs", integer, JobsHelp} ]. %% From 16c5de8aeaae63dd2bf423b9d1a970355f104ea1 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 8 Mar 2010 21:59:28 +0100 Subject: [PATCH 5/8] Add commands option to bash completion Add -c/--commands option to the bash completion script. --- priv/shell-completion/bash/rebar | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/priv/shell-completion/bash/rebar b/priv/shell-completion/bash/rebar index a7a1426..b01f6f6 100644 --- a/priv/shell-completion/bash/rebar +++ b/priv/shell-completion/bash/rebar @@ -6,8 +6,8 @@ _rebar() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - sopts="-h -v -f -j" - lopts=" --help --verbose --force --jobs=" + sopts="-h -c -v -f -j" + lopts=" --help --commands --verbose --force --jobs=" cmdsnvars="analyze build_plt check_plt clean compile \ create-app create-node eunit generate \ install int_test perf_test test \ From 62a2788e8b61ea371e4a41261c33476125150501 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 8 Mar 2010 22:59:50 +0100 Subject: [PATCH 6/8] Update TODO file one item done, another one saved --- TODO | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TODO b/TODO index e464181..f921ce0 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,2 @@ +* write documentation * ZSH completion script -* rebar option or command to list all available - commands/tasks From faf21694fe890a4b10a1fdd1c3ae8ec470c13aa5 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Thu, 11 Mar 2010 01:27:46 +0100 Subject: [PATCH 7/8] Make sure zip module is loaded Before we check for zip:foldl/3 make sure zip module is loaded. --- src/rebar_utils.erl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 0ac6cf1..e7d22fa 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -116,6 +116,7 @@ abort(String, Args) -> %% this function when the time is right. escript:foldl/3 was an %% undocumented exported fun and is going to be removed post-R13B04. escript_foldl(Fun, Acc, File) -> + {module, zip} = code:ensure_loaded(zip), case erlang:function_exported(zip, foldl, 3) of true -> emulate_escript_foldl(Fun, Acc, File); From 459b312adab8fc25d72f7f3255db23c4cf44e24f Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Thu, 11 Mar 2010 01:40:06 +0100 Subject: [PATCH 8/8] Add template variable to bash completion Add create command's template variable to bash completion. --- priv/shell-completion/bash/rebar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/shell-completion/bash/rebar b/priv/shell-completion/bash/rebar index b01f6f6..ba87bdd 100644 --- a/priv/shell-completion/bash/rebar +++ b/priv/shell-completion/bash/rebar @@ -11,7 +11,7 @@ _rebar() cmdsnvars="analyze build_plt check_plt clean compile \ create-app create-node eunit generate \ install int_test perf_test test \ - case= force=1 jobs= suite= verbose=1 appid= target=" + case= force=1 jobs= suite= verbose=1 appid= target= template=" if [[ ${cur} == --* ]] ; then COMPREPLY=( $(compgen -W "${lopts}" -- ${cur}) )