Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

157 lignes
6.0 KiB

il y a 15 ans
il y a 15 ans
il y a 15 ans
il y a 15 ans
il y a 14 ans
il y a 15 ans
il y a 15 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. %% -------------------------------------------------------------------
  4. %%
  5. %% rebar: Erlang Build Tools
  6. %%
  7. %% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
  8. %%
  9. %% Permission is hereby granted, free of charge, to any person obtaining a copy
  10. %% of this software and associated documentation files (the "Software"), to deal
  11. %% in the Software without restriction, including without limitation the rights
  12. %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. %% copies of the Software, and to permit persons to whom the Software is
  14. %% furnished to do so, subject to the following conditions:
  15. %%
  16. %% The above copyright notice and this permission notice shall be included in
  17. %% all copies or substantial portions of the Software.
  18. %%
  19. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. %% THE SOFTWARE.
  26. %% -------------------------------------------------------------------
  27. -module(rebar_file_utils).
  28. -export([rm_rf/1,
  29. cp_r/2,
  30. mv/2,
  31. delete_each/1]).
  32. -include("rebar.hrl").
  33. %% ===================================================================
  34. %% Public API
  35. %% ===================================================================
  36. %% @doc Remove files and directories.
  37. %% Target is a single filename, directoryname or wildcard expression.
  38. -spec rm_rf(Target::string()) -> ok.
  39. rm_rf(Target) ->
  40. case os:type() of
  41. {unix, _} ->
  42. EscTarget = re:replace(Target, " ", "\\\\ ",
  43. [global, {return, list}]),
  44. {ok, []} = rebar_utils:sh(?FMT("rm -rf ~s", [EscTarget]),
  45. [{use_stdout, false}, return_on_error]),
  46. ok;
  47. {win32, _} ->
  48. Filelist = filelib:wildcard(Target),
  49. Dirs = [F || F <- Filelist, filelib:is_dir(F)],
  50. Files = Filelist -- Dirs,
  51. ok = delete_each(Files),
  52. ok = delete_each_dir_win32(Dirs),
  53. ok
  54. end.
  55. -spec cp_r(Sources::list(string()), Dest::file:filename()) -> ok.
  56. cp_r(Sources, Dest) ->
  57. case os:type() of
  58. {unix, _} ->
  59. QuotedSources = ["\"" ++ Src ++ "\"" || Src <- Sources],
  60. SourceStr = string:join(QuotedSources, " "),
  61. {ok, []} = rebar_utils:sh(?FMT("cp -R ~s \"~s\"",
  62. [SourceStr, Dest]),
  63. [{use_stdout, false}, return_on_error]),
  64. ok;
  65. {win32, _} ->
  66. lists:foreach(fun(Src) -> ok = cp_r_win32(Src,Dest) end, Sources),
  67. ok
  68. end.
  69. -spec mv(Source::string(), Dest::file:filename()) -> ok.
  70. mv(Source, Dest) ->
  71. case os:type() of
  72. {unix, _} ->
  73. {ok, []} = rebar_utils:sh(?FMT("mv \"~s\" \"~s\"", [Source, Dest]),
  74. [{use_stdout, false}, return_on_error]),
  75. ok;
  76. {win32, _} ->
  77. {ok, R} = rebar_utils:sh(
  78. ?FMT("cmd " "/c move /y \"~s\" \"~s\" 1> nul",
  79. [filename:nativename(Source),
  80. filename:nativename(Dest)]),
  81. [{use_stdout, false}, return_on_error]),
  82. case R of
  83. [] ->
  84. ok;
  85. _ ->
  86. {error, lists:flatten(
  87. io_lib:format("Failed to move ~s to ~s~n",
  88. [Source, Dest]))}
  89. end
  90. end.
  91. delete_each([]) ->
  92. ok;
  93. delete_each([File | Rest]) ->
  94. case file:delete(File) of
  95. ok ->
  96. delete_each(Rest);
  97. {error, enoent} ->
  98. delete_each(Rest);
  99. {error, Reason} ->
  100. ?ERROR("Failed to delete file ~s: ~p\n", [File, Reason]),
  101. ?FAIL
  102. end.
  103. %% ===================================================================
  104. %% Internal functions
  105. %% ===================================================================
  106. delete_each_dir_win32([]) -> ok;
  107. delete_each_dir_win32([Dir | Rest]) ->
  108. {ok, []} = rebar_utils:sh(?FMT("cmd /c rd /q /s \"~s\"",
  109. [filename:nativename(Dir)]),
  110. [{use_stdout, false}, return_on_error]),
  111. delete_each_dir_win32(Rest).
  112. xcopy_win32(Source,Dest)->
  113. {ok, R} = rebar_utils:sh(
  114. ?FMT("cmd /c xcopy \"~s\" \"~s\" /q /y /e 2> nul",
  115. [filename:nativename(Source), filename:nativename(Dest)]),
  116. [{use_stdout, false}, return_on_error]),
  117. case length(R) > 0 of
  118. %% when xcopy fails, stdout is empty and and error message is printed
  119. %% to stderr (which is redirected to nul)
  120. true -> ok;
  121. false ->
  122. {error, lists:flatten(
  123. io_lib:format("Failed to xcopy from ~s to ~s~n",
  124. [Source, Dest]))}
  125. end.
  126. cp_r_win32({true, SourceDir}, {true, DestDir}) ->
  127. %% from directory to directory
  128. SourceBase = filename:basename(SourceDir),
  129. ok = case file:make_dir(filename:join(DestDir, SourceBase)) of
  130. {error, eexist} -> ok;
  131. Other -> Other
  132. end,
  133. ok = xcopy_win32(SourceDir, filename:join(DestDir, SourceBase));
  134. cp_r_win32({false, Source} = S,{true, DestDir}) ->
  135. %% from file to directory
  136. cp_r_win32(S, {false, filename:join(DestDir, filename:basename(Source))});
  137. cp_r_win32({false, Source},{false, Dest}) ->
  138. %% from file to file
  139. {ok,_} = file:copy(Source, Dest),
  140. ok;
  141. cp_r_win32(Source,Dest) ->
  142. Dst = {filelib:is_dir(Dest), Dest},
  143. lists:foreach(fun(Src) ->
  144. ok = cp_r_win32({filelib:is_dir(Src), Src}, Dst)
  145. end, filelib:wildcard(Source)),
  146. ok.