summaryrefslogtreecommitdiff
path: root/src/rebar_file_utils.erl
diff options
context:
space:
mode:
authoralisdair sullivan <alisdair.sullivan@askuity.com>2015-09-12 17:36:34 -0700
committeralisdair sullivan <alisdair.sullivan@askuity.com>2015-09-13 00:07:44 -0700
commit6a8948544838073d5c5f829403ee7e7f1d6cf4d9 (patch)
treec2877aabe6748da20ed87a9ba9da1e0e83c997c0 /src/rebar_file_utils.erl
parentadb2550b3a19ca8d22bdca73ab3180367e27dc2e (diff)
extract `retarget_path/2', `relative_path/2' and `reduce_path/1' and
add tests
Diffstat (limited to 'src/rebar_file_utils.erl')
-rw-r--r--src/rebar_file_utils.erl29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl
index 732d83f..26d4da0 100644
--- a/src/rebar_file_utils.erl
+++ b/src/rebar_file_utils.erl
@@ -37,7 +37,9 @@
system_tmpdir/0,
system_tmpdir/1,
reset_dir/1,
- touch/1]).
+ touch/1,
+ relative_path/2,
+ reduce_path/1]).
-include("rebar.hrl").
@@ -244,6 +246,31 @@ touch(Path) ->
ok = file:write_file_info(Path, A#file_info{mtime = calendar:local_time(),
atime = calendar:local_time()}).
+%% for a given path return the path relative to a base directory
+-spec relative_path(string(), string()) -> {ok, string()} | {error, not_relative}.
+
+relative_path(Target, To) ->
+ relative_path1(filename:split(reduce_path(Target)),
+ filename:split(reduce_path(To))).
+
+relative_path1([Part|Target], [Part|To]) -> relative_path1(Target, To);
+relative_path1([], []) -> {ok, ""};
+relative_path1(Target, []) -> {ok, filename:join(Target)};
+relative_path1(_, _) -> {error, not_relative}.
+
+
+%% reduce a filepath by removing all incidences of `.' and `..'
+-spec reduce_path(string()) -> string().
+
+reduce_path(Dir) -> reduce_path([], filename:split(filename:absname(Dir))).
+
+reduce_path([], []) -> filename:nativename("/");
+reduce_path(Acc, []) -> filename:join(lists:reverse(Acc));
+reduce_path(Acc, ["."|Rest]) -> reduce_path(Acc, Rest);
+reduce_path([_|Acc], [".."|Rest]) -> reduce_path(Acc, Rest);
+reduce_path([], [".."|Rest]) -> reduce_path([], Rest);
+reduce_path(Acc, [Component|Rest]) -> reduce_path([Component|Acc], Rest).
+
%% ===================================================================
%% Internal functions
%% ===================================================================