diff options
-rw-r--r-- | priv/templates/escript.template | 11 | ||||
-rw-r--r-- | priv/templates/escript_README.md | 14 | ||||
-rw-r--r-- | priv/templates/escript_mod.erl | 17 | ||||
-rw-r--r-- | priv/templates/escript_rebar.config | 13 | ||||
-rw-r--r-- | src/rebar_packages.erl | 13 | ||||
-rw-r--r-- | src/rebar_prv_common_test.erl | 42 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 13 | ||||
-rw-r--r-- | test/rebar_ct_SUITE.erl | 36 |
8 files changed, 144 insertions, 15 deletions
diff --git a/priv/templates/escript.template b/priv/templates/escript.template new file mode 100644 index 0000000..c0afd3c --- /dev/null +++ b/priv/templates/escript.template @@ -0,0 +1,11 @@ +{description, "Escriptized application"}. +{variables, [ + {name, "mylib", "Name of the OTP application to be escriptized"}, + {desc, "An escript", "Short description of the project"} +]}. +{template, "escript_mod.erl", "{{name}}/src/{{name}}.erl"}. +{template, "otp_lib.app.src", "{{name}}/src/{{name}}.app.src"}. +{template, "escript_rebar.config", "{{name}}/rebar.config"}. +{template, "gitignore", "{{name}}/.gitignore"}. +{template, "LICENSE", "{{name}}/LICENSE"}. +{template, "escript_README.md", "{{name}}/README.md"}. diff --git a/priv/templates/escript_README.md b/priv/templates/escript_README.md new file mode 100644 index 0000000..577d679 --- /dev/null +++ b/priv/templates/escript_README.md @@ -0,0 +1,14 @@ +{{name}} +===== + +{{desc}} + +Build +----- + + $ rebar3 escriptize + +Run +--- + + $ _build/default/bin/{{name}} diff --git a/priv/templates/escript_mod.erl b/priv/templates/escript_mod.erl new file mode 100644 index 0000000..f8a779b --- /dev/null +++ b/priv/templates/escript_mod.erl @@ -0,0 +1,17 @@ +-module({{name}}). + +%% API exports +-export([main/1]). + +%%==================================================================== +%% API functions +%%==================================================================== + +%% escript Entry point +main(Args) -> + io:format("Args: ~p~n", [Args]), + erlang:halt(0). + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/priv/templates/escript_rebar.config b/priv/templates/escript_rebar.config new file mode 100644 index 0000000..196f835 --- /dev/null +++ b/priv/templates/escript_rebar.config @@ -0,0 +1,13 @@ +{erl_opts, [no_debug_info]}. +{deps, []}. + +{escript_incl_apps, + [{{name}}]}. +{escript_top_level_app, {{name}}}. +{escript_name, {{name}}}. +{escript_emu_args, "%%! +sbtu +A0\n"}. + +%% Profiles +{profiles, [{test, + [{erl_opts, [debug_info]} + ]}]}. diff --git a/src/rebar_packages.erl b/src/rebar_packages.erl index fb2d094..4ab5f9f 100644 --- a/src/rebar_packages.erl +++ b/src/rebar_packages.erl @@ -2,6 +2,7 @@ -export([get_packages/1 ,registry/1 + ,check_registry/3 ,find_highest_matching/3]). -export_type([package/0]). @@ -52,6 +53,18 @@ registry(State) -> error end. +check_registry(Pkg, Vsn, State) -> + case rebar_state:registry(State) of + {ok, T} -> + case ets:lookup(T, Pkg) of + [{Pkg, [Vsns]}] -> + lists:member(Vsn, Vsns); + _ -> + false + end; + error -> + false + end. %% Hex supports use of ~> to specify the version required for a dependency. %% Since rebar3 requires exact versions to choose from we find the highest diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index 9038759..d4370de 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -280,23 +280,25 @@ find_suite_dirs(Suites) -> %% eliminate duplicates lists:usort(AllDirs). -copy(State, Target) -> - case reduce_path(Target) == rebar_state:dir(State) of +copy(State, Dir) -> + From = reduce_path(Dir), + case From == rebar_state:dir(State) of true -> throw({error, suite_at_project_root}); false -> ok end, - case retarget_path(State, Target) of + case retarget_path(State, From) of %% directory lies outside of our project's file structure so %% don't copy it - Target -> Target; - NewTarget -> - %% unlink the directory if it's a symlink - case ec_file:is_symlink(NewTarget) of - true -> ok = ec_file:remove(NewTarget); + From -> From; + Target -> + %% recursively delete any symlinks in the target directory + %% if it exists so we don't smash files in the linked dirs + case ec_file:is_dir(Target) of + true -> remove_links(Target); false -> ok end, - ok = ec_file:copy(Target, NewTarget, [recursive]), - NewTarget + ok = ec_file:copy(From, Target, [recursive]), + Target end. compile_dir(State, Dir, OutDir) -> @@ -343,6 +345,26 @@ reduce_path([_|Acc], [".."|Rest]) -> reduce_path(Acc, Rest); reduce_path([], [".."|Rest]) -> reduce_path([], Rest); reduce_path(Acc, [Component|Rest]) -> reduce_path([Component|Acc], Rest). +remove_links(Path) -> + case ec_file:is_dir(Path) of + false -> ok; + true -> remove_links1(Path) + end. + +remove_links1(Path) -> + case ec_file:is_symlink(Path) of + true -> + file:delete(Path); + false -> + lists:foreach(fun(ChildPath) -> + remove_links(ChildPath) + end, sub_dirs(Path)) + end. + +sub_dirs(Path) -> + {ok, SubDirs} = file:list_dir(Path), + [filename:join(Path, SubDir) || SubDir <- SubDirs]. + replace_src_dirs(State, Dirs) -> %% replace any `src_dirs` with the test dirs ErlOpts = rebar_state:get(State, erl_opts, []), diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 5aa34c3..3fb2d71 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -99,6 +99,8 @@ format_error({bad_constraint, Name, Constraint}) -> io_lib:format("Unable to parse version for package ~s: ~s", [Name, Constraint]); format_error({parse_dep, Dep}) -> io_lib:format("Failed parsing dep ~p", [Dep]); +format_error({not_rebar_package, Package, Version}) -> + io_lib:format("Package not buildable with rebar3: ~s-~s", [Package, Version]); format_error({missing_package, Package, Version}) -> io_lib:format("Package not found in registry: ~s-~s", [Package, Version]); format_error({cycles, Cycles}) -> @@ -210,7 +212,7 @@ update_pkg_deps(Profile, Pkgs, Packages, Upgrade, Seen, State) -> {Solved, State1}. handle_pkg_dep(Profile, Pkg, Packages, Upgrade, DepsDir, Fetched, Seen, State) -> - AppInfo = package_to_app(DepsDir, Packages, Pkg), + AppInfo = package_to_app(DepsDir, Packages, Pkg, State), Level = rebar_app_info:dep_level(AppInfo), {NewSeen, NewState} = maybe_lock(Profile, AppInfo, Seen, State, Level), {_, AppInfo1} = maybe_fetch(AppInfo, Profile, Upgrade, Seen, NewState), @@ -242,10 +244,15 @@ maybe_lock(Profile, AppInfo, Seen, State, Level) -> {Seen, State} end. -package_to_app(DepsDir, Packages, {Name, Vsn, Level}) -> +package_to_app(DepsDir, Packages, {Name, Vsn, Level}, State) -> case dict:find({Name, Vsn}, Packages) of error -> - throw(?PRV_ERROR({missing_package, Name, Vsn})); + case rebar_packages:check_registry(Name, Vsn, State) of + true -> + throw(?PRV_ERROR({not_rebar_package, Name, Vsn})); + false -> + throw(?PRV_ERROR({missing_package, Name, Vsn})) + end; {ok, P} -> PkgDeps = [{PkgName, PkgVsn} || {PkgName,PkgVsn} <- proplists:get_value(<<"deps">>, P, [])], diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 3c4aed3..0a86127 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -16,7 +16,8 @@ single_unmanaged_suite/1, multi_suite/1, all_suite/1, - single_dir_and_single_suite/1]). + single_dir_and_single_suite/1, + symlinked_dir_overwritten_fix/1]). -include_lib("common_test/include/ct.hrl"). @@ -36,7 +37,8 @@ groups() -> [{basic_app, [], [basic_app_default_dirs, single_unmanaged_suite, multi_suite, all_suite, - single_dir_and_single_suite]}]. + single_dir_and_single_suite, + symlinked_dir_overwritten_fix]}]. init_per_group(basic_app, Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_"), @@ -513,6 +515,36 @@ single_dir_and_single_suite(Config) -> Expect = Suite. +symlinked_dir_overwritten_fix(Config) -> + AppDir = ?config(apps, Config), + [Name1, _Name2] = ?config(appnames, Config), + + {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return), + + LibDirs = rebar_dir:lib_dirs(State), + State1 = rebar_app_discover:do(State, LibDirs), + + Providers = rebar_state:providers(State1), + Namespace = rebar_state:namespace(State1), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, + ["--dir=" ++ filename:join([AppDir, + "apps", + Name1])]), + + State2 = rebar_state:command_parsed_args(State1, GetOptResult), + + Result = rebar_prv_common_test:setup_ct(State2), + + Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1])), + Dir = proplists:get_value(dir, Result), + + Expect = Dir, + + {ok, _} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return). + + test_suite(Name) -> io_lib:format("-module(~ts_SUITE).\n" "-compile(export_all).\n" |