diff options
| author | Tristan Sloughter <tristan.sloughter@gmail.com> | 2015-05-08 08:54:41 -0500 | 
|---|---|---|
| committer | Tristan Sloughter <tristan.sloughter@gmail.com> | 2015-05-08 08:54:41 -0500 | 
| commit | f79b14068f9e65da9c4719411c537bf14248e7c9 (patch) | |
| tree | f632ff37bb40a53f803f0a44507821f201ea6b43 /bootstrap | |
| parent | d128bffcddf42b07a25bf61424cc679adadb83f2 (diff) | |
| parent | b4724009b5b8823b57c78c2cecac51875acb317a (diff) | |
Merge pull request #400 from tsloughter/ingwinlu-fix_windows_bootstrap
Ingwinlu fix windows bootstrap
Diffstat (limited to 'bootstrap')
| -rwxr-xr-x | bootstrap | 105 | 
1 files changed, 104 insertions, 1 deletions
| @@ -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,114 @@ 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; +               _ -> +                   make_relative_path(Source, Target) +           end, +    case file:make_symlink(Link, Target) of +        ok -> +            ok; +        {error, eexist} -> +            ok; +        {error, _} -> +            cp_r([Source], Target) +    end. + +make_relative_path(Source, Target) -> +    do_make_relative_path(filename:split(Source), filename:split(Target)). + +do_make_relative_path([H|T1], [H|T2]) -> +    do_make_relative_path(T1, T2); +do_make_relative_path(Source, Target) -> +    Base = lists:duplicate(max(length(Target) - 1, 0), ".."), +    filename:join(Base ++ Source). + +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), | 
