diff options
-rw-r--r-- | src/rebar_file_utils.erl | 16 | ||||
-rw-r--r-- | test/rebar_file_utils_SUITE.erl | 21 |
2 files changed, 26 insertions, 11 deletions
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl index 8c57d19..0f84520 100644 --- a/src/rebar_file_utils.erl +++ b/src/rebar_file_utils.erl @@ -262,9 +262,11 @@ path_from_ancestor_(_, _) -> {error, badparent}. %% reduce a filepath by removing all incidences of `.' and `..' -spec canonical_path(string()) -> string(). -canonical_path(Dir) -> canonical_path([], filename:split(filename:absname(Dir))). +canonical_path(Dir) -> + Canon = canonical_path([], filename:split(filename:absname(Dir))), + filename:nativename(Canon). -canonical_path([], []) -> filename:nativename("/"); +canonical_path([], []) -> filename:absname("/"); canonical_path(Acc, []) -> filename:join(lists:reverse(Acc)); canonical_path(Acc, ["."|Rest]) -> canonical_path(Acc, Rest); canonical_path([_|Acc], [".."|Rest]) -> canonical_path(Acc, Rest); @@ -283,13 +285,19 @@ delete_each_dir_win32([Dir | Rest]) -> delete_each_dir_win32(Rest). xcopy_win32(Source,Dest)-> - %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Chanegd to robocopy to + %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Changed to robocopy to %% handle long names. May have issues with older windows. Cmd = case filelib:is_dir(Source) of true -> + %% For robocopy, copying /a/b/c/ to /d/e/f/ recursively does not + %% create /d/e/f/c/*, but rather copies all files to /d/e/f/*. + %% The usage we make here expects the former, not the later, so we + %% must manually add the last fragment of a directory to the `Dest` + %% in order to properly replicate POSIX platforms + NewDest = filename:join([Dest, filename:basename(Source)]), ?FMT("robocopy \"~s\" \"~s\" /e /is 1> nul", [rebar_utils:escape_double_quotes(filename:nativename(Source)), - rebar_utils:escape_double_quotes(filename:nativename(Dest))]); + rebar_utils:escape_double_quotes(filename:nativename(NewDest))]); false -> ?FMT("robocopy \"~s\" \"~s\" \"~s\" /e /is 1> nul", [rebar_utils:escape_double_quotes(filename:nativename(filename:dirname(Source))), diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index a061325..c1f85b3 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/test/rebar_file_utils_SUITE.erl @@ -97,10 +97,17 @@ path_from_ancestor(_Config) -> ?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo/bar/baz/qux")). canonical_path(_Config) -> - ?assertEqual(filename:nativename("/"), rebar_file_utils:canonical_path("/")), - ?assertEqual(filename:nativename("/"), rebar_file_utils:canonical_path("/../../..")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/bar/..")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/../foo")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/.")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/./.")), - ?assertEqual("/foo/bar", rebar_file_utils:canonical_path("/foo/./bar")).
\ No newline at end of file + %% We find the root so that the name works both on unix-likes and + %% with Windows. + Root = case os:type() of + {win32, _} -> filename:nativename(filename:absname("/")); % C:\, with proper drive + _ -> "/" + end, + ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/")), + ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/../../..")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/bar/..")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/../foo")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/.")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/./.")), + ?assertEqual(filename:nativename(Root ++ "foo/bar"), + rebar_file_utils:canonical_path("/foo/./bar")). |