summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rebar_file_utils.erl16
-rw-r--r--test/rebar_file_utils_SUITE.erl21
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")).