Przeglądaj źródła

fix bootstrap on windows, fallback to copy if symlinking fails

pull/399/head
derwinlu 10 lat temu
rodzic
commit
3e005ab107
1 zmienionych plików z 95 dodań i 1 usunięć
  1. +95
    -1
      bootstrap

+ 95
- 1
bootstrap Wyświetl plik

@ -2,6 +2,7 @@
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
%% ex: ft=erlang ts=4 sw=4 et
main(_Args) ->
%% Fetch and build deps required to build rebar3
BaseDeps = [{providers, []}
@ -105,12 +106,105 @@ compile_file(File, Opts) ->
bootstrap_rebar3() ->
filelib:ensure_dir("_build/default/lib/rebar/ebin/dummy.beam"),
code:add_path("_build/default/lib/rebar/ebin/"),
file:make_symlink(filename:absname("src"), filename:absname("_build/default/lib/rebar/src")),
ok = symlink_or_copy(filename:absname("src"),
filename:absname("_build/default/lib/rebar/src")),
Sources = ["src/rebar_resource.erl" | filelib:wildcard("src/*.erl")],
[compile_file(X, [{outdir, "_build/default/lib/rebar/ebin/"}
,return | additional_defines()]) || X <- Sources],
code:add_patha(filename:absname("_build/default/lib/rebar/ebin")).
%%rebar.hrl
-define(FMT(Str, Args), lists:flatten(io_lib:format(Str, Args))).
%%/rebar.hrl
%%rebar_file_utils
symlink_or_copy(Source, Target) ->
Link = case os:type() of
{win32, _} ->
Source;
_ ->
rebar_dir:make_relative_path(Source, Target)
end,
case file:make_symlink(Link, Target) of
ok ->
ok;
{error, eexist} ->
ok;
{error, _} ->
cp_r([Source], Target)
end.
cp_r([], _Dest) ->
ok;
cp_r(Sources, Dest) ->
case os:type() of
{unix, _} ->
EscSources = [escape_path(Src) || Src <- Sources],
SourceStr = string:join(EscSources, " "),
os:cmd(?FMT("cp -R ~s \"~s\"", [SourceStr, Dest])),
ok;
{win32, _} ->
lists:foreach(fun(Src) -> ok = cp_r_win32(Src,Dest) end, Sources),
ok
end.
xcopy_win32(Source,Dest)->
R = os:cmd(?FMT("xcopy \"~s\" \"~s\" /q /y /e 2> nul",
[filename:nativename(Source), filename:nativename(Dest)])),
case length(R) > 0 of
%% when xcopy fails, stdout is empty and and error message is printed
%% to stderr (which is redirected to nul)
true -> ok;
false ->
{error, lists:flatten(
io_lib:format("Failed to xcopy from ~s to ~s~n",
[Source, Dest]))}
end.
cp_r_win32({true, SourceDir}, {true, DestDir}) ->
%% from directory to directory
SourceBase = filename:basename(SourceDir),
ok = case file:make_dir(filename:join(DestDir, SourceBase)) of
{error, eexist} -> ok;
Other -> Other
end,
ok = xcopy_win32(SourceDir, filename:join(DestDir, SourceBase));
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.
escape_path(Str) ->
re:replace(Str, "([ ()?])", "\\\\&", [global, {return, list}]).
%%/rebar_file_utils
setup_env() ->
%% We don't need or want relx providers loaded yet
application:load(rebar),

Ładowanie…
Anuluj
Zapisz