From 04a945375a63542811d3af7bd14bc7d5c5b303d9 Mon Sep 17 00:00:00 2001 From: Daniel Widgren Date: Thu, 11 Jun 2015 14:44:44 +0200 Subject: Fixing test for windows, changing symlink to symlink_or_copy --- src/rlx_cmd_args.erl | 2 ++ src/rlx_prv_assembler.erl | 4 +-- src/rlx_util.erl | 85 +++++++++++++++++++++++++++++++++++++++++++++- test/rlx_command_SUITE.erl | 3 +- test/rlx_release_SUITE.erl | 58 ++++++++++++++++++++++--------- 5 files changed, 132 insertions(+), 20 deletions(-) diff --git a/src/rlx_cmd_args.erl b/src/rlx_cmd_args.erl index 2039b43..309282e 100644 --- a/src/rlx_cmd_args.erl +++ b/src/rlx_cmd_args.erl @@ -318,6 +318,8 @@ convert_overrides([Override | Rest], Acc) case re:split(Override, ":") of [AppName, AppDir] -> convert_overrides(Rest, [{rlx_util:to_atom(AppName), AppDir} | Acc]); + [AppName, Drive, AppDir] -> + convert_overrides(Rest, [{rlx_util:to_atom(AppName), <>} | Acc]); _ -> ?RLX_ERROR({failed_to_parse_override, Override}) end; diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl index 79768d3..a3715e5 100644 --- a/src/rlx_prv_assembler.erl +++ b/src/rlx_prv_assembler.erl @@ -257,7 +257,7 @@ remove_symlink_or_directory(TargetDir) -> end. link_directory(AppDir, TargetDir) -> - case file:make_symlink(AppDir, TargetDir) of + case rlx_util:symlink_or_copy(AppDir, TargetDir) of {error, Reason} -> ?RLX_ERROR({unable_to_make_symlink, AppDir, TargetDir, Reason}); ok -> @@ -433,7 +433,7 @@ copy_or_symlink_config_file(State, ConfigPath, RelConfPath) -> ensure_not_exist(RelConfPath), case rlx_state:dev_mode(State) of true -> - ok = file:make_symlink(ConfigPath, RelConfPath); + ok = rlx_util:symlink_or_copy(ConfigPath, RelConfPath); _ -> ok = ec_file:copy(ConfigPath, RelConfPath) end. diff --git a/src/rlx_util.erl b/src/rlx_util.erl index 8a54ae6..db448e8 100644 --- a/src/rlx_util.erl +++ b/src/rlx_util.erl @@ -37,7 +37,8 @@ render/2, load_file/3, template_files/0, - escript_foldl/3]). + escript_foldl/3, + symlink_or_copy/2]). -define(ONE_LEVEL_INDENT, " "). %%============================================================================ @@ -212,6 +213,88 @@ escript_foldl(Fun, Acc, File) -> Error end. +symlink_or_copy(Source, Target) -> + case file:make_symlink(Source, Target) of + ok -> + ok; + {error, eexist} -> + ok; + {error, _} -> + case os:type() of + {win32, _} -> + win32_symlink(Source, Target); + _ -> + case filelib:is_dir(Target) of + true -> ok; + false -> + cp_r([Source], Target) + end + end + end. + + +win32_symlink(Source, Target) -> + os:cmd("cmd /c mklink /j " ++ Target ++ " " ++ Source), + ok. + +-spec cp_r(list(string()), file:filename()) -> 'ok'. +cp_r([], _Dest) -> + ok; +cp_r(Sources, Dest) -> + case os:type() of + {unix, _} -> + ok; + {win32, _} -> + lists:foreach(fun(Src) -> ok = cp_r_win32(Src,Dest) end, Sources), + ok + end. + +xcopy_win32(Source,Dest)-> + %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Chanegd to robocopy to + %% handle long names. May have issues with older windows. + os:cmd("robocopy " ++ Source ++ " " ++ Dest ++ " /e /is"), + ok. + +cp_r_win32({true, SourceDir}, {true, DestDir}) -> + %% from directory to directory + ok = case file:make_dir(DestDir) of + {error, eexist} -> ok; + Other -> Other + end, + ok = xcopy_win32(SourceDir, DestDir); +cp_r_win32({false, Source} = S,{true, DestDir}) -> + %% from file to directory + cp_r_win32(S, {false, filename:join(DestDir, filename:basename(Source))}); +cp_r_win32({false, Source},{false, Dest}) -> + %% from file to file + {ok,_} = file:copy(Source, Dest), + ok; +cp_r_win32({true, SourceDir}, {false, DestDir}) -> + case filelib:is_regular(DestDir) of + true -> + %% From directory to file? This shouldn't happen + {error, lists:flatten( + io_lib:format("Cannot copy dir (~p) to file (~p)\n", + [SourceDir, DestDir]))}; + false -> + %% Specifying a target directory that doesn't currently exist. + %% So let's attempt to create this directory + case filelib:ensure_dir(filename:join(DestDir, "dummy")) of + ok -> + ok = xcopy_win32(SourceDir, DestDir); + {error, Reason} -> + {error, lists:flatten( + io_lib:format("Unable to create dir ~p: ~p\n", + [DestDir, Reason]))} + end + end; +cp_r_win32(Source,Dest) -> + Dst = {filelib:is_dir(Dest), Dest}, + lists:foreach(fun(Src) -> + ok = cp_r_win32({filelib:is_dir(Src), Src}, Dst) + end, filelib:wildcard(Source)), + ok. + %%%=================================================================== %%% Test Functions %%%=================================================================== diff --git a/test/rlx_command_SUITE.erl b/test/rlx_command_SUITE.erl index db2794d..9d1513f 100644 --- a/test/rlx_command_SUITE.erl +++ b/test/rlx_command_SUITE.erl @@ -63,7 +63,8 @@ normal_passing_case(Config) -> {ok, State} = rlx_cmd_args:args2state(Opts, Targets), {ok, State1} = rlx_config:do(State), Overrides = rlx_state:overrides(State1), - ?assertMatch([{lib1, Lib1}], Overrides), + ct:pal("Overrides: ~p~n", [Overrides]), + ?assertMatch([{lib1,Lib1}], Overrides), ?assertMatch([Lib1, Lib2], rlx_state:lib_dirs(State1)), ?assertMatch(Outdir, rlx_state:base_output_dir(State1)), diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl index 9b09ab9..cf98822 100644 --- a/test/rlx_release_SUITE.erl +++ b/test/rlx_release_SUITE.erl @@ -281,9 +281,15 @@ make_overridden_release(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({OverrideAppName, OverrideVsn}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)), - {ok, Real} = file:read_link(filename:join([OutputDir, "foo", "lib", - OverrideApp ++ "-" ++ OverrideVsn])), - ?assertMatch(OverrideAppDir, Real). + case os:type() of + {win32, _} -> + filelib:is_file(filename:join([OutputDir, "foo", "lib", + OverrideApp ++ "-" ++ OverrideVsn])); + _ -> + {ok, Real} = file:read_link(filename:join([OutputDir, "foo", "lib", + OverrideApp ++ "-" ++ OverrideVsn])), + ?assertMatch(OverrideAppDir, Real) + end. make_skip_app_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -493,9 +499,15 @@ make_rerun_overridden_release(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({OverrideAppName, OverrideVsn}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)), - {ok, Real} = file:read_link(filename:join([OutputDir, "foo", "lib", - OverrideApp ++ "-" ++ OverrideVsn])), - ?assertMatch(OverrideAppDir, Real). + case os:type() of + {win32, _} -> + filelib:is_file(filename:join([OutputDir, "foo", "lib", + OverrideApp ++ "-" ++ OverrideVsn])); + _ -> + {ok, Real} = file:read_link(filename:join([OutputDir, "foo", "lib", + OverrideApp ++ "-" ++ OverrideVsn])), + ?assertMatch(OverrideAppDir, Real) + end. overlay_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -845,16 +857,30 @@ make_dev_mode_release(Config) -> {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 3, OutputDir, ConfigFile), [{{foo, "0.0.1"}, _Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)), - - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))), - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))), - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_1-0.0.1"]))), - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))), - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))), - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", - "sys.config"]))), - ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", - "vm.args"]))). + + + case os:type() of + {unix, _} -> + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_1-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", + "sys.config"]))), + ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1", + "vm.args"]))); + {win32, _} -> + ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))), + ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))), + ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "goal_app_1-0.0.1"]))), + ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))), + ?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))), + ?assert(filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "sys.config"]))), + ?assert(filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "vm.args"]))) + end. make_config_script_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), -- cgit v1.2.3