From 3db8f585f11eb7d7a9573d9f3a5480f6a900e6d7 Mon Sep 17 00:00:00 2001 From: Tim Watson Date: Wed, 26 Jan 2011 02:00:53 +0000 Subject: [PATCH 01/13] Add -spec support to rebar_ct command line This change adds support for executing ct test runs based on test specificiations, which was missing previously. The rebar_ct module now looks for any number of files with a name ending in `test.spec` and if it finds one or more, passes these after the `-spec` argument to ct_run instead of explicitly configuring the config, user config and coverage config variables. When no specifications are found, then the module behaves as it did before this change, and both the ct1 and (new) ct2 integration tests appear to show this is a backwards compatible patch. --- include/rebar.hrl | 1 - inttest/ct2/ct2_rt.erl | 26 +++++++++++++++ inttest/ct2/foo.test.spec | 1 + inttest/ct2/foo_SUITE.erl | 10 ++++++ src/rebar_ct.erl | 70 +++++++++++++++++++++++++++------------ 5 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 inttest/ct2/ct2_rt.erl create mode 100644 inttest/ct2/foo.test.spec create mode 100644 inttest/ct2/foo_SUITE.erl diff --git a/include/rebar.hrl b/include/rebar.hrl index d5eaff5..66d6318 100644 --- a/include/rebar.hrl +++ b/include/rebar.hrl @@ -15,4 +15,3 @@ -define(ERROR(Str, Args), rebar_log:log(error, Str, Args)). -define(FMT(Str, Args), lists:flatten(io_lib:format(Str, Args))). - diff --git a/inttest/ct2/ct2_rt.erl b/inttest/ct2/ct2_rt.erl new file mode 100644 index 0000000..2b14ff9 --- /dev/null +++ b/inttest/ct2/ct2_rt.erl @@ -0,0 +1,26 @@ +-module(ct2_rt). + +-compile(export_all). + + +files() -> + [{create, "ebin/foo.app", app(foo)}, + {copy, "../../rebar", "rebar"}, + {copy, "foo.test.spec", "test/foo.test.spec"}, + {copy, "foo_SUITE.erl", "test/foo_SUITE.erl"}]. + +run(_Dir) -> + {ok, _} = retest:sh("./rebar compile ct -v"), + ok. + +%% +%% Generate the contents of a simple .app file +%% +app(Name) -> + App = {application, Name, + [{description, atom_to_list(Name)}, + {vsn, "1"}, + {modules, []}, + {registered, []}, + {applications, [kernel, stdlib]}]}, + io_lib:format("~p.\n", [App]). diff --git a/inttest/ct2/foo.test.spec b/inttest/ct2/foo.test.spec new file mode 100644 index 0000000..f3e4cb0 --- /dev/null +++ b/inttest/ct2/foo.test.spec @@ -0,0 +1 @@ +{suites, "test", all}. diff --git a/inttest/ct2/foo_SUITE.erl b/inttest/ct2/foo_SUITE.erl new file mode 100644 index 0000000..d03aedf --- /dev/null +++ b/inttest/ct2/foo_SUITE.erl @@ -0,0 +1,10 @@ +-module(foo_SUITE). + +-include_lib("common_test/include/ct.hrl"). + +-compile(export_all). + +all() -> [foo]. + +foo(Config) -> + io:format("Test: ~p\n", [Config]). diff --git a/src/rebar_ct.erl b/src/rebar_ct.erl index 8f7c71a..a66bdce 100644 --- a/src/rebar_ct.erl +++ b/src/rebar_ct.erl @@ -141,32 +141,57 @@ make_cmd(TestDir, Config) -> CodeDirs = [io_lib:format("\"~s\"", [Dir]) || Dir <- [EbinDir|NonLibCodeDirs]], CodePathString = string:join(CodeDirs, " "), - Cmd = ?FMT("erl " % should we expand ERL_PATH? - " -noshell -pa ~s ~s" - " -s ct_run script_start -s erlang halt" - " -name test@~s" - " -logdir \"~s\"" - " -env TEST_DIR \"~s\"", - [CodePathString, - Include, - net_adm:localhost(), - LogDir, - filename:join(Cwd, TestDir)]) ++ - get_cover_config(Config, Cwd) ++ - get_ct_config_file(TestDir) ++ - get_config_file(TestDir) ++ - get_suite(TestDir) ++ - get_case(), + Cmd = case get_ct_specs(Cwd) of + undefined -> + ?FMT("erl " % should we expand ERL_PATH? + " -noshell -pa ~s ~s" + " -s ct_run script_start -s erlang halt" + " -name test@~s" + " -logdir \"~s\"" + " -env TEST_DIR \"~s\"", + [CodePathString, + Include, + net_adm:localhost(), + LogDir, + filename:join(Cwd, TestDir)]) ++ + get_cover_config(Config, Cwd) ++ + get_ct_config_file(TestDir) ++ + get_config_file(TestDir) ++ + get_suite(TestDir) ++ + get_case(); + SpecFlags -> + ?FMT("erl " % should we expand ERL_PATH? + " -noshell -pa ~s ~s" + " -s ct_run script_start -s erlang halt" + " -name test@~s" + " -logdir \"~s\"" + " -env TEST_DIR \"~s\"", + [CodePathString, + Include, + net_adm:localhost(), + LogDir, + filename:join(Cwd, TestDir)]) ++ + SpecFlags ++ get_cover_config(Config, Cwd) + end, RawLog = filename:join(LogDir, "raw.log"), {Cmd, RawLog}. +get_ct_specs(Cwd) -> + case collect_glob(Cwd, ".*\.test\.spec\$") of + [] -> undefined; + [Spec] -> + " -spec " ++ Spec; + Specs -> + " -spec " ++ + lists:flatten([io_lib:format("~s ", [Spec]) || Spec <- Specs]) + end. + get_cover_config(Config, Cwd) -> case rebar_config:get_local(Config, cover_enabled, false) of false -> ""; true -> - case filelib:fold_files(Cwd, ".*cover\.spec\$", - true, fun collect_ct_specs/2, []) of + case collect_glob(Cwd, ".*cover\.spec\$") of [] -> ?DEBUG("No cover spec found: ~s~n", [Cwd]), ""; @@ -178,15 +203,18 @@ get_cover_config(Config, Cwd) -> end end. -collect_ct_specs(F, Acc) -> +collect_glob(Cwd, Glob) -> + filelib:fold_files(Cwd, Glob, true, fun collect_files/2, []). + +collect_files(F, Acc) -> %% Ignore any specs under the deps/ directory. Do this pulling %% the dirname off the the F and then splitting it into a list. Parts = filename:split(filename:dirname(F)), case lists:member("deps", Parts) of true -> - Acc; % There is a directory named "deps" in path + Acc; % There is a directory named "deps" in path false -> - [F | Acc] % No "deps" directory in path + [F | Acc] % No "deps" directory in path end. get_ct_config_file(TestDir) -> From 5049da8ec4a1db76b13bf081a2d489fdb15a4775 Mon Sep 17 00:00:00 2001 From: Tim Dysinger Date: Sun, 20 Feb 2011 13:52:22 -1000 Subject: [PATCH 02/13] Add fail_on_warning support for LFE --- src/rebar_lfe_compiler.erl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl index b100e3d..6ea0724 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_lfe_compiler.erl @@ -41,12 +41,11 @@ compile(Config, _AppFile) -> rebar_base_compiler:run(Config, FirstFiles, "src", ".lfe", "ebin", ".beam", fun compile_lfe/3). - %% =================================================================== %% Internal functions %% =================================================================== -compile_lfe(Source, _Target, Config) -> +compile_lfe(Source, Target, Config) -> case code:which(lfe_comp) of non_existing -> ?CONSOLE( @@ -59,9 +58,14 @@ compile_lfe(Source, _Target, Config) -> ?FAIL; _ -> Opts = [{i, "include"}, {outdir, "ebin"}, report, return] ++ - rebar_config:get_list(Config, lfe_opts, []), - case lfe_comp:file(Source,Opts) of + rebar_config:get_list(Config, erl_opts, []), + case lfe_comp:file(Source, Opts) of {ok, _, []} -> ok; + {ok, _, _Warnings} -> + case lists:member(fail_on_warning, Opts) of + true -> file:delete(Target), ?FAIL; + false -> ok + end; _ -> ?FAIL end end. From 6f97e6e55bc36b0c2960f4854a43787275236add Mon Sep 17 00:00:00 2001 From: Tim Dysinger Date: Sun, 20 Feb 2011 14:05:13 -1000 Subject: [PATCH 03/13] Add up to date instructions in case LFE is missing --- src/rebar_lfe_compiler.erl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl index 6ea0724..95d2e84 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_lfe_compiler.erl @@ -48,13 +48,17 @@ compile(Config, _AppFile) -> compile_lfe(Source, Target, Config) -> case code:which(lfe_comp) of non_existing -> - ?CONSOLE( - <<"~n===============================================~n" - " You need to install LFE to compile LFE source files~n" - "Download the latest tarball release from github~n" - " https://github.com/rvirding/lfe/downloads~n" - " and install it into your erlang library dir~n" - "===============================================~n~n">>, []), + ?CONSOLE(<< + "~n" + "*** MISSING LFE COMPILER ***~n" + " You must do one of the following:~n" + " a) Install LFE globally in your erl libs~n" + " b) Add LFE as a dep for your project, eg:~n" + " {lfe, \"0.6.1\",~n" + " {git, \"git://github.com/rvirding/lfe\",~n" + " {tag, \"v0.6.1\"}}}~n" + "~n" + >>, []), ?FAIL; _ -> Opts = [{i, "include"}, {outdir, "ebin"}, report, return] ++ From c6f6e8a572fe4760aaa9d36d77ab2b9209534054 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 21 Feb 2011 15:36:50 +0100 Subject: [PATCH 04/13] Fix Dialyzer warning and slightly reformat code --- src/rebar_lfe_compiler.erl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl index 95d2e84..dc97bb1 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_lfe_compiler.erl @@ -64,11 +64,15 @@ compile_lfe(Source, Target, Config) -> Opts = [{i, "include"}, {outdir, "ebin"}, report, return] ++ rebar_config:get_list(Config, erl_opts, []), case lfe_comp:file(Source, Opts) of - {ok, _, []} -> ok; + {ok, _, []} -> + ok; {ok, _, _Warnings} -> case lists:member(fail_on_warning, Opts) of - true -> file:delete(Target), ?FAIL; - false -> ok + true -> + ok = file:delete(Target), + ?FAIL; + false -> + ok end; _ -> ?FAIL end From 3356c2d9e87c9bbad082bd3eeccecea0b6cc4358 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 21 Feb 2011 17:42:10 +0100 Subject: [PATCH 05/13] Use erlang:function_exported/3 --- src/rebar_core.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rebar_core.erl b/src/rebar_core.erl index db3e0b4..b390dc0 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -280,8 +280,8 @@ expand_lib_dirs([Dir | Rest], Root, Acc) -> select_modules([], _Command, Acc) -> lists:reverse(Acc); select_modules([Module | Rest], Command, Acc) -> - Exports = Module:module_info(exports), - case lists:member({Command, 2}, Exports) of + {module, Module} = code:ensure_loaded(Module), + case erlang:function_exported(Module, Command, 2) of true -> select_modules(Rest, Command, [Module | Acc]); false -> From 2cff499a342f5bcb978e88fd453764afac6d5817 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Tue, 22 Feb 2011 15:46:34 +0100 Subject: [PATCH 06/13] Fix regression in rebar_lfe_compiler --- src/rebar_lfe_compiler.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl index dc97bb1..06b0f08 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_lfe_compiler.erl @@ -62,7 +62,7 @@ compile_lfe(Source, Target, Config) -> ?FAIL; _ -> Opts = [{i, "include"}, {outdir, "ebin"}, report, return] ++ - rebar_config:get_list(Config, erl_opts, []), + rebar_config:get_list(Config, lfe_opts, []), case lfe_comp:file(Source, Opts) of {ok, _, []} -> ok; @@ -74,6 +74,7 @@ compile_lfe(Source, Target, Config) -> false -> ok end; - _ -> ?FAIL + _ -> + ?FAIL end end. From 90d2ce5e0770be25179376af87ce861c33c1ba14 Mon Sep 17 00:00:00 2001 From: joewilliams Date: Fri, 25 Feb 2011 10:16:52 -0500 Subject: [PATCH 07/13] Ignore app files not in ebin --- src/rebar_appups.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rebar_appups.erl b/src/rebar_appups.erl index ab5af29..ec1df0a 100644 --- a/src/rebar_appups.erl +++ b/src/rebar_appups.erl @@ -56,10 +56,10 @@ "Reltool and .rel release names do not match~n", []), %% Get lists of the old and new app files - OldAppFiles = rebar_utils:find_files( - filename:join([OldVerPath, "lib"]), "^.*.app$"), - NewAppFiles = rebar_utils:find_files( - filename:join([NewName, "lib"]), "^.*.app$"), + OldAppFiles = filelib:wildcard( + filename:join([OldVerPath, "lib", "*", "ebin", "*.app"])), + NewAppFiles = filelib:wildcard( + filename:join([NewName, "lib", "*", "ebin", "*.app"])), %% Find all the apps that have been upgraded UpgradedApps = get_upgraded_apps(OldAppFiles, NewAppFiles), From 58661a92e205b44a5090f9a2c4371a94bab692ec Mon Sep 17 00:00:00 2001 From: Juan Jose Comellas Date: Tue, 22 Feb 2011 01:58:46 -0300 Subject: [PATCH 08/13] Convert the entries in the code path to absolute paths Rebar will exit with {error,bad_directory} when trying to restore the code path after it has finished working on a subdirectory if there are invalid relative paths in it. The problem was seen when executing the last line of rebar_erlc_compiler:doterl_compile/3 (true = code:set_path(CurrPath)). --- src/rebar_core.erl | 4 ++++ src/rebar_utils.erl | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/rebar_core.erl b/src/rebar_core.erl index b390dc0..d92af34 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -76,6 +76,10 @@ process_commands([Command | Rest]) -> lists:foreach(fun (D) -> erlang:erase({skip_dir, D}) end, skip_dirs()), Operations = erlang:get(operations), + %% Convert the code path so that all the entries are absolute paths. + %% If not, code:set_path() may choke on invalid relative paths when trying + %% to restore the code path from inside a subdirectory. + true = rebar_utils:expand_code_path(), _ = process_dir(rebar_utils:get_cwd(), rebar_config:new(), Command, sets:new()), case erlang:get(operations) of diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 2822c0f..8898b8a 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -38,7 +38,8 @@ abort/2, escript_foldl/3, find_executable/1, - prop_check/3]). + prop_check/3, + expand_code_path/0]). -include("rebar.hrl"). @@ -156,6 +157,14 @@ find_executable(Name) -> prop_check(true, _, _) -> true; prop_check(false, Msg, Args) -> ?ABORT(Msg, Args). +%% Convert all the entries in the code path to absolute paths. +expand_code_path() -> + CodePath = lists:foldl(fun (Path, Acc) -> + [filename:absname(Path) | Acc] + end, [], code:get_path()), + code:set_path(lists:reverse(CodePath)). + + %% ==================================================================== %% Internal functions %% ==================================================================== From 0a603435f5132d18e19d445e7b0c27361c9505f0 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Tue, 1 Feb 2011 20:37:03 -0800 Subject: [PATCH 09/13] honor local deps before code path --- src/rebar_deps.erl | 75 ++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/src/rebar_deps.erl b/src/rebar_deps.erl index 69f5fc1..22ef09e 100644 --- a/src/rebar_deps.erl +++ b/src/rebar_deps.erl @@ -131,7 +131,7 @@ compile(Config, AppFile) -> 'delete-deps'(Config, _) -> %% Delete all the available deps in our deps/ directory, if any - DepsDir = get_deps_dir(), + {true, DepsDir} = get_deps_dir(), Deps = rebar_config:get_local(Config, deps, []), {AvailableDeps, _} = find_deps(find, Deps), _ = [delete_dep(D) @@ -154,9 +154,21 @@ set_global_deps_dir(_Config, _DepsDir) -> ok. get_deps_dir() -> + get_deps_dir(""). + +get_deps_dir(App) -> BaseDir = rebar_config:get_global(base_dir, []), DepsDir = rebar_config:get_global(deps_dir, "deps"), - filename:join(BaseDir, DepsDir). + {true, filename:join([BaseDir, DepsDir, App])}. + +get_lib_dir(App) -> + % Find App amongst the reachable lib directories + % Returns either the found path or a tagged tuple with a boolean + % to match get_deps_dir's return type + case code:lib_dir(App) of + {error, bad_name} -> {false, bad_name}; + Path -> {true, Path} + end. update_deps_code_path([]) -> ok; @@ -189,24 +201,42 @@ find_deps(Mode, [{App, VsnRegex, Source} | Rest], Acc) -> Dep = #dep { app = App, vsn_regex = VsnRegex, source = Source }, - case is_app_available(App, VsnRegex) of - {true, AppDir} -> - find_deps(Mode, Rest, acc_deps(Mode, avail, Dep, AppDir, Acc)); - {false, _} -> - AppDir = filename:join(get_deps_dir(), Dep#dep.app), - case is_app_available(App, VsnRegex, AppDir) of - {true, AppDir} -> - find_deps(Mode, Rest, - acc_deps(Mode, avail, Dep, AppDir, Acc)); - {false, _} -> - find_deps(Mode, Rest, - acc_deps(Mode, missing, Dep, AppDir, Acc)) - end - end; + {Availability, FoundDir} = find_dep(Dep), + find_deps(Mode, Rest, acc_deps(Mode, Availability, Dep, FoundDir, Acc)); find_deps(_Mode, [Other | _Rest], _Acc) -> ?ABORT("Invalid dependency specification ~p in ~s\n", [Other, rebar_utils:get_cwd()]). +find_dep(Dep) -> + % Find a dep based on its source, + % e.g. {git, "https://github.com/mochi/mochiweb.git", "HEAD"} + % Deps with a source must be found (or fetched) locally. + % Those without a source may be satisfied from lib directories (get_lib_dir). + find_dep(Dep, Dep#dep.source). + +find_dep(Dep, undefined) -> + % 'source' is undefined. If Dep is not satisfied locally, + % go ahead and find it amongst the lib_dir's. + case find_dep_in_dir(Dep, get_deps_dir(Dep#dep.app)) of + {avail, Dir} -> {avail, Dir}; + {missing, _} -> find_dep_in_dir(Dep, get_lib_dir(Dep#dep.app)) + end; +find_dep(Dep, _Source) -> + % _Source is defined. Regardless of what it is, we must find it + % locally satisfied or fetch it from the original source + % into the project's deps + find_dep_in_dir(Dep, get_deps_dir(Dep#dep.app)). + +find_dep_in_dir(_Dep, {false, Dir}) -> + {missing, Dir}; +find_dep_in_dir(Dep, {true, Dir}) -> + App = Dep#dep.app, + VsnRegex = Dep#dep.vsn_regex, + case is_app_available(App, VsnRegex, Dir) of + {true, _AppFile} -> {avail, Dir}; + {false, _} -> {missing, Dir} + end. + acc_deps(find, avail, Dep, AppDir, {Avail, Missing}) -> {[Dep#dep { dir = AppDir } | Avail], Missing}; acc_deps(find, missing, Dep, AppDir, {Avail, Missing}) -> @@ -227,15 +257,8 @@ require_source_engine(Source) -> true = source_engine_avail(Source), ok. -is_app_available(App, VsnRegex) -> - case code:lib_dir(App) of - {error, bad_name} -> - {false, bad_name}; - Path -> - is_app_available(App, VsnRegex, Path) - end. - is_app_available(App, VsnRegex, Path) -> + ?DEBUG("is_app_available, looking for App ~p with Path ~p~n", [App, Path]), case rebar_app_utils:is_app_dir(Path) of {true, AppFile} -> case rebar_app_utils:app_name(AppFile) of @@ -293,7 +316,7 @@ use_source(Dep, Count) -> false -> ?CONSOLE("Pulling ~p from ~p\n", [Dep#dep.app, Dep#dep.source]), require_source_engine(Dep#dep.source), - TargetDir = filename:join(get_deps_dir(), Dep#dep.app), + {true, TargetDir} = get_deps_dir(Dep#dep.app), download_source(TargetDir, Dep#dep.source), use_source(Dep#dep { dir = TargetDir }, Count-1) end. @@ -335,7 +358,7 @@ update_source(Dep) -> %% VCS directory, such as when a source archive is built of a project, with %% all deps already downloaded/included. So, verify that the necessary VCS %% directory exists before attempting to do the update. - AppDir = filename:join(get_deps_dir(), Dep#dep.app), + {true, AppDir} = get_deps_dir(Dep#dep.app), case has_vcs_dir(element(1, Dep#dep.source), AppDir) of true -> ?CONSOLE("Updating ~p from ~p\n", [Dep#dep.app, Dep#dep.source]), From d725e5fe926da14812c2d1f18e021dbcee1a9cad Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Thu, 3 Mar 2011 17:40:24 +0100 Subject: [PATCH 10/13] Add Christopher Brown to THANKS file --- THANKS | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS b/THANKS index e20f433..80bc830 100644 --- a/THANKS +++ b/THANKS @@ -43,3 +43,4 @@ Jesper Louis Andersen Richard Jones Tim Watson Anders 'andekar' +Christopher Brown From 0f99ba22804abe2f69f1425b82f6dc1d098ab441 Mon Sep 17 00:00:00 2001 From: joewilliams Date: Thu, 3 Mar 2011 10:39:44 -0800 Subject: [PATCH 11/13] Fix bug that causes appup generation to fail This commit changes how rebar determines which apps have been updated, added and removed from a release during appup generation. Rather than use app files it now determines this from the rel file in each version of the release. In addition it fixes a bug reported on the mailing list when generating appups when an application has been added or removed from either release. --- src/rebar_appups.erl | 38 +++++++++++++++++++------------------- src/rebar_rel_utils.erl | 27 ++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/rebar_appups.erl b/src/rebar_appups.erl index ec1df0a..079d596 100644 --- a/src/rebar_appups.erl +++ b/src/rebar_appups.erl @@ -55,14 +55,8 @@ NewName == OldName, "Reltool and .rel release names do not match~n", []), - %% Get lists of the old and new app files - OldAppFiles = filelib:wildcard( - filename:join([OldVerPath, "lib", "*", "ebin", "*.app"])), - NewAppFiles = filelib:wildcard( - filename:join([NewName, "lib", "*", "ebin", "*.app"])), - %% Find all the apps that have been upgraded - UpgradedApps = get_upgraded_apps(OldAppFiles, NewAppFiles), + UpgradedApps = get_upgraded_apps(Name, OldVerPath, NewVerPath), %% Get a list of any appup files that exist in the new release NewAppUpFiles = rebar_utils:find_files( @@ -85,18 +79,24 @@ %% Internal functions %% =================================================================== -get_upgraded_apps(OldAppFiles, NewAppFiles) -> - OldAppsVer = [{rebar_app_utils:app_name(AppFile), - rebar_app_utils:app_vsn(AppFile)} || AppFile <- OldAppFiles], - NewAppsVer = [{rebar_app_utils:app_name(AppFile), - rebar_app_utils:app_vsn(AppFile)} || AppFile <- NewAppFiles], - UpgradedApps = lists:subtract(NewAppsVer, OldAppsVer), - lists:map( - fun({App, NewVer}) -> - {App, OldVer} = proplists:lookup(App, OldAppsVer), - {App, {OldVer, NewVer}} - end, - UpgradedApps). +get_upgraded_apps(Name, OldVerPath, NewVerPath) -> + OldApps = rebar_rel_utils:get_rel_apps(Name, OldVerPath), + NewApps = rebar_rel_utils:get_rel_apps(Name, NewVerPath), + + Sorted = lists:umerge(lists:sort(NewApps), lists:sort(OldApps)), + AddedorChanged = lists:subtract(Sorted, OldApps), + DeletedorChanged = lists:subtract(Sorted, NewApps), + ?DEBUG("Added or Changed: ~p~n", [AddedorChanged]), + ?DEBUG("Deleted or Changed: ~p~n", [DeletedorChanged]), + + AddedDeletedChanged = lists:ukeysort(1, lists:append(DeletedorChanged, + AddedorChanged)), + UpgradedApps = lists:subtract(AddedorChanged, AddedDeletedChanged), + ?DEBUG("Upgraded Apps:~p~n", [UpgradedApps]), + + [{AppName, {proplists:get_value(AppName, OldApps), NewVer}} + || {AppName, NewVer} <- UpgradedApps]. + file_to_name(File) -> filename:rootname(filename:basename(File)). diff --git a/src/rebar_rel_utils.erl b/src/rebar_rel_utils.erl index 9729e20..d3baf4d 100644 --- a/src/rebar_rel_utils.erl +++ b/src/rebar_rel_utils.erl @@ -31,7 +31,10 @@ get_reltool_release_info/1, get_rel_release_info/1, get_rel_release_info/2, - get_previous_release_path/0]). + get_rel_apps/1, + get_rel_apps/2, + get_previous_release_path/0, + get_rel_file_path/2]). -include("rebar.hrl"). @@ -70,11 +73,29 @@ get_rel_release_info(RelFile) -> %% Get release name and version from a name and a path get_rel_release_info(Name, Path) -> + RelPath = get_rel_file_path(Name, Path), + get_rel_release_info(RelPath). + +%% Get list of apps included in a release from a rel file +get_rel_apps(RelFile) -> + case file:consult(RelFile) of + {ok, [{release, _, _, Apps}]} -> + Apps; + _ -> + ?ABORT("Failed to parse ~s~n", [RelFile]) + end. + +%% Get list of apps included in a release from a name and a path +get_rel_apps(Name, Path) -> + RelPath = get_rel_file_path(Name, Path), + get_rel_apps(RelPath). + +%% Get rel file path from name and path +get_rel_file_path(Name, Path) -> [RelFile] = filelib:wildcard(filename:join([Path, "releases", "*", Name ++ ".rel"])), [BinDir|_] = re:replace(RelFile, Name ++ "\\.rel", ""), - get_rel_release_info(filename:join([binary_to_list(BinDir), - Name ++ ".rel"])). + filename:join([binary_to_list(BinDir), Name ++ ".rel"]). %% Get the previous release path from a global variable get_previous_release_path() -> From 6c3c3606e59c2cac5b8f1b35f09b704dd3c894ab Mon Sep 17 00:00:00 2001 From: Alexey Romanov Date: Mon, 21 Feb 2011 12:57:24 +0300 Subject: [PATCH 12/13] Add console_clean to usage message for simplenode --- priv/templates/simplenode.runner | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/templates/simplenode.runner b/priv/templates/simplenode.runner index 18fa951..43dce0f 100755 --- a/priv/templates/simplenode.runner +++ b/priv/templates/simplenode.runner @@ -147,7 +147,7 @@ case "$1" in ;; *) - echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach}" + echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|console_clean|attach}" exit 1 ;; esac From 25c0226ab94560c5e182944c4c71b9f71ac3f08e Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Fri, 4 Mar 2011 19:39:45 +0100 Subject: [PATCH 13/13] Update runner script in test project --- test/upgrade_project/rel/files/dummy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/upgrade_project/rel/files/dummy b/test/upgrade_project/rel/files/dummy index ec6d7ff..43dce0f 100755 --- a/test/upgrade_project/rel/files/dummy +++ b/test/upgrade_project/rel/files/dummy @@ -7,6 +7,7 @@ RUNNER_SCRIPT_DIR=$(cd ${0%/*} && pwd) RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*} RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc RUNNER_LOG_DIR=$RUNNER_BASE_DIR/log +# Note the trailing slash on $PIPE_DIR/ PIPE_DIR=/tmp/$RUNNER_BASE_DIR/ RUNNER_USER= @@ -61,8 +62,7 @@ case "$1" in HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT start" export HEART_COMMAND mkdir -p $PIPE_DIR - # Note the trailing slash on $PIPE_DIR/ - $ERTS_PATH/run_erl -daemon $PIPE_DIR/ $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console" 2>&1 + $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console" 2>&1 ;; stop) @@ -147,7 +147,7 @@ case "$1" in ;; *) - echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach}" + echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|console_clean|attach}" exit 1 ;; esac