diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar_file_utils.erl | 37 | ||||
-rw-r--r-- | src/rebar_git_resource.erl | 32 | ||||
-rw-r--r-- | src/rebar_hg_resource.erl | 29 | ||||
-rw-r--r-- | src/rebar_prv_compile.erl | 2 | ||||
-rw-r--r-- | src/rebar_prv_eunit.erl | 62 | ||||
-rw-r--r-- | src/rebar_utils.erl | 17 |
6 files changed, 96 insertions, 83 deletions
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl index b4cdc27..da58c00 100644 --- a/src/rebar_file_utils.erl +++ b/src/rebar_file_utils.erl @@ -98,7 +98,8 @@ symlink_or_copy(Source, Target) -> win32_symlink(Source, Target) -> Res = rebar_utils:sh( ?FMT("cmd /c mklink /j \"~s\" \"~s\"", - [filename:nativename(Target), filename:nativename(Source)]), + [rebar_utils:escape_double_quotes(filename:nativename(Target)), + rebar_utils:escape_double_quotes(filename:nativename(Source))]), [{use_stdout, false}, return_on_error]), case win32_ok(Res) of true -> ok; @@ -115,7 +116,7 @@ win32_symlink(Source, Target) -> rm_rf(Target) -> case os:type() of {unix, _} -> - EscTarget = escape_path(Target), + EscTarget = rebar_utils:escape_chars(Target), {ok, []} = rebar_utils:sh(?FMT("rm -rf ~s", [EscTarget]), [{use_stdout, false}, abort_on_error]), ok; @@ -134,10 +135,10 @@ cp_r([], _Dest) -> cp_r(Sources, Dest) -> case os:type() of {unix, _} -> - EscSources = [escape_path(Src) || Src <- Sources], + EscSources = [rebar_utils:escape_chars(Src) || Src <- Sources], SourceStr = string:join(EscSources, " "), {ok, []} = rebar_utils:sh(?FMT("cp -R ~s \"~s\"", - [SourceStr, Dest]), + [SourceStr, rebar_utils:escape_double_quotes(Dest)]), [{use_stdout, false}, abort_on_error]), ok; {win32, _} -> @@ -149,8 +150,8 @@ cp_r(Sources, Dest) -> mv(Source, Dest) -> case os:type() of {unix, _} -> - EscSource = escape_path(Source), - EscDest = escape_path(Dest), + EscSource = rebar_utils:escape_chars(Source), + EscDest = rebar_utils:escape_chars(Dest), {ok, []} = rebar_utils:sh(?FMT("mv ~s ~s", [EscSource, EscDest]), [{use_stdout, false}, abort_on_error]), ok; @@ -158,13 +159,13 @@ mv(Source, Dest) -> Cmd = case filelib:is_dir(Source) of true -> ?FMT("robocopy /move /s \"~s\" \"~s\" 1> nul", - [filename:nativename(Source), - filename:nativename(Dest)]); + [rebar_utils:escape_double_quotes(filename:nativename(Source)), + rebar_utils:escape_double_quotes(filename:nativename(Dest))]); false -> ?FMT("robocopy /move /s \"~s\" \"~s\" \"~s\" 1> nul", - [filename:nativename(filename:dirname(Source)), - filename:nativename(Dest), - filename:basename(Source)]) + [rebar_utils:escape_double_quotes(filename:nativename(filename:dirname(Source))), + rebar_utils:escape_double_quotes(filename:nativename(Dest)), + rebar_utils:escape_double_quotes(filename:basename(Source))]) end, Res = rebar_utils:sh(Cmd, [{use_stdout, false}, return_on_error]), @@ -250,7 +251,7 @@ touch(Path) -> delete_each_dir_win32([]) -> ok; delete_each_dir_win32([Dir | Rest]) -> {ok, []} = rebar_utils:sh(?FMT("rd /q /s \"~s\"", - [filename:nativename(Dir)]), + [rebar_utils:escape_double_quotes(filename:nativename(Dir))]), [{use_stdout, false}, return_on_error]), delete_each_dir_win32(Rest). @@ -260,13 +261,13 @@ xcopy_win32(Source,Dest)-> Cmd = case filelib:is_dir(Source) of true -> ?FMT("robocopy \"~s\" \"~s\" /e /is 1> nul", - [filename:nativename(Source), - filename:nativename(Dest)]); + [rebar_utils:escape_double_quotes(filename:nativename(Source)), + rebar_utils:escape_double_quotes(filename:nativename(Dest))]); false -> ?FMT("robocopy \"~s\" \"~s\" \"~s\" /e /is 1> nul", - [filename:nativename(filename:dirname(Source)), - filename:nativename(Dest), - filename:basename(Source)]) + [rebar_utils:escape_double_quotes(filename:nativename(filename:dirname(Source))), + rebar_utils:escape_double_quotes(filename:nativename(Dest)), + rebar_utils:escape_double_quotes(filename:basename(Source))]) end, Res = rebar_utils:sh(Cmd, [{use_stdout, false}, return_on_error]), @@ -318,5 +319,3 @@ cp_r_win32(Source,Dest) -> end, filelib:wildcard(Source)), ok. -escape_path(Str) -> - re:replace(Str, "([ ()?])", "\\\\&", [global, {return, list}]). diff --git a/src/rebar_git_resource.erl b/src/rebar_git_resource.erl index e2f3f69..aec1535 100644 --- a/src/rebar_git_resource.erl +++ b/src/rebar_git_resource.erl @@ -16,7 +16,7 @@ lock(AppDir, {git, Url, _}) -> lock(AppDir, {git, Url}) -> AbortMsg = io_lib:format("Locking of git dependency failed in ~s", [AppDir]), {ok, VsnString} = - rebar_utils:sh("git --git-dir=\"" ++ AppDir ++ "/.git\" rev-parse --verify HEAD", + rebar_utils:sh("git --git-dir=\"" ++ rebar_utils:escape_double_quotes(AppDir) ++ "/.git\" rev-parse --verify HEAD", [{use_stdout, false}, {debug_abort_on_error, AbortMsg}]), Ref = string:strip(VsnString, both, $\n), {git, Url, {ref, Ref}}. @@ -32,10 +32,11 @@ needs_update(Dir, {git, Url, {tag, Tag}}) -> not ((Current1 =:= Tag) andalso compare_url(Dir, Url)); needs_update(Dir, {git, Url, {branch, Branch}}) -> %% Fetch remote so we can check if the branch has changed - {ok, _} = rebar_utils:sh(?FMT("git fetch origin ~s", [Branch]), + SafeBranch = rebar_utils:escape_chars(Branch), + {ok, _} = rebar_utils:sh(?FMT("git fetch origin ~s", [SafeBranch]), [{cd, Dir}]), %% Check for new commits to origin/Branch - {ok, Current} = rebar_utils:sh(?FMT("git log HEAD..origin/~s --oneline", [Branch]), + {ok, Current} = rebar_utils:sh(?FMT("git log HEAD..origin/~s --oneline", [SafeBranch]), [{cd, Dir}]), ?DEBUG("Checking git branch ~s for updates", [Branch]), not ((Current =:= []) andalso compare_url(Dir, Url)); @@ -93,24 +94,33 @@ download(Dir, {git, Url, ""}, State) -> download(Dir, {git, Url, {branch, Branch}}, _State) -> ok = filelib:ensure_dir(Dir), rebar_utils:sh(?FMT("git clone ~s ~s -b ~s --single-branch", - [Url, filename:basename(Dir), Branch]), + [rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir)), + rebar_utils:escape_chars(Branch)]), [{cd, filename:dirname(Dir)}]); download(Dir, {git, Url, {tag, Tag}}, _State) -> ok = filelib:ensure_dir(Dir), rebar_utils:sh(?FMT("git clone ~s ~s -b ~s --single-branch", - [Url, filename:basename(Dir), Tag]), + [rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir)), + rebar_utils:escape_chars(Tag)]), [{cd, filename:dirname(Dir)}]); download(Dir, {git, Url, {ref, Ref}}, _State) -> ok = filelib:ensure_dir(Dir), - rebar_utils:sh(?FMT("git clone -n ~s ~s", [Url, filename:basename(Dir)]), + rebar_utils:sh(?FMT("git clone -n ~s ~s", + [rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir))]), [{cd, filename:dirname(Dir)}]), rebar_utils:sh(?FMT("git checkout -q ~s", [Ref]), [{cd, Dir}]); download(Dir, {git, Url, Rev}, _State) -> ?WARN("WARNING: It is recommended to use {branch, Name}, {tag, Tag} or {ref, Ref}, otherwise updating the dep may not work as expected.", []), ok = filelib:ensure_dir(Dir), - rebar_utils:sh(?FMT("git clone -n ~s ~s", [Url, filename:basename(Dir)]), + rebar_utils:sh(?FMT("git clone -n ~s ~s", + [rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir))]), [{cd, filename:dirname(Dir)}]), - rebar_utils:sh(?FMT("git checkout -q ~s", [Rev]), [{cd, Dir}]). + rebar_utils:sh(?FMT("git checkout -q ~s", [rebar_utils:escape_chars(Rev)]), + [{cd, Dir}]). make_vsn(Dir) -> {Vsn, RawRef, RawCount} = collect_default_refcount(Dir), @@ -133,9 +143,10 @@ collect_default_refcount(Dir) -> {ok, RawCount} = case Tag of undefined -> - AbortMsg2 = "Getting rev-list of git depedency failed in " ++ rebar_dir:get_cwd(), + AbortMsg2 = "Getting rev-list of git depedency failed in " ++ Dir, {ok, PatchLines} = rebar_utils:sh("git rev-list HEAD", [{use_stdout, false}, + {cd, Dir}, {debug_abort_on_error, AbortMsg2}]), rebar_utils:line_count(PatchLines); _ -> @@ -161,9 +172,10 @@ get_patch_count(Dir, RawRef) -> AbortMsg = "Getting rev-list of git dep failed in " ++ Dir, Ref = re:replace(RawRef, "\\s", "", [global]), Cmd = io_lib:format("git rev-list ~s..HEAD", - [Ref]), + [rebar_utils:escape_chars(Ref)]), {ok, PatchLines} = rebar_utils:sh(Cmd, [{use_stdout, false}, + {cd, Dir}, {debug_abort_on_error, AbortMsg}]), rebar_utils:line_count(PatchLines). diff --git a/src/rebar_hg_resource.erl b/src/rebar_hg_resource.erl index a67abb9..7d03eda 100644 --- a/src/rebar_hg_resource.erl +++ b/src/rebar_hg_resource.erl @@ -57,26 +57,34 @@ download(Dir, {hg, Url, ""}, State) -> download(Dir, {hg, Url, {branch, Branch}}, _State) -> ok = filelib:ensure_dir(Dir), rebar_utils:sh(?FMT("hg clone -q -b ~s ~s ~s", - [Branch, Url, filename:basename(Dir)]), + [rebar_utils:escape_chars(Branch), + rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir))]), [{cd, filename:dirname(Dir)}]); download(Dir, {hg, Url, {tag, Tag}}, _State) -> ok = filelib:ensure_dir(Dir), rebar_utils:sh(?FMT("hg clone -q -u ~s ~s ~s", - [Tag, Url, filename:basename(Dir)]), + [rebar_utils:escape_chars(Tag), + rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir))]), [{cd, filename:dirname(Dir)}]); download(Dir, {hg, Url, {ref, Ref}}, _State) -> ok = filelib:ensure_dir(Dir), rebar_utils:sh(?FMT("hg clone -q -r ~s ~s ~s", - [Ref, Url, filename:basename(Dir)]), + [rebar_utils:escape_chars(Ref), + rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir))]), [{cd, filename:dirname(Dir)}]); download(Dir, {hg, Url, Rev}, _State) -> ok = filelib:ensure_dir(Dir), rebar_utils:sh(?FMT("hg clone -q -r ~s ~s ~s", - [Rev, Url, filename:basename(Dir)]), + [rebar_utils:escape_chars(Rev), + rebar_utils:escape_chars(Url), + rebar_utils:escape_chars(filename:basename(Dir))]), [{cd, filename:dirname(Dir)}]). make_vsn(Dir) -> - BaseHg = "hg -R '" ++ Dir ++ "' ", + BaseHg = "hg -R \"" ++ rebar_utils:escape_double_quotes(Dir) ++ "\" ", Ref = get_ref(Dir), Cmd = BaseHg ++ "log --template \"{latesttag}+build.{latesttagdistance}.rev.{node|short}\"" " --rev " ++ Ref, @@ -95,23 +103,23 @@ make_vsn(Dir) -> %%% Internal functions compare_url(Dir, Url) -> - CurrentUrl = string:strip(os:cmd("hg -R '" ++ Dir ++"' paths default"), both, $\n), + CurrentUrl = string:strip(os:cmd("hg -R \"" ++ rebar_utils:escape_double_quotes(Dir) ++"\" paths default"), both, $\n), CurrentUrl1 = string:strip(CurrentUrl, both, $\r), parse_hg_url(CurrentUrl1) =:= parse_hg_url(Url). get_ref(Dir) -> AbortMsg = io_lib:format("Get ref of hg dependency failed in ~s", [Dir]), {ok, RefString} = - rebar_utils:sh("hg -R '" ++ Dir ++ "' --debug id -i", + rebar_utils:sh("hg -R \"" ++ rebar_utils:escape_double_quotes(Dir) ++ "\" --debug id -i", [{use_stdout, false}, {debug_abort_on_error, AbortMsg}]), string:strip(RefString, both, $\n). get_tag_distance(Dir, Ref) -> AbortMsg = io_lib:format("Get tag distance of hg dependency failed in ~s", [Dir]), {ok, LogString} = - rebar_utils:sh("hg -R '" ++ Dir ++ "' " + rebar_utils:sh("hg -R \"" ++ rebar_utils:escape_double_quotes(Dir) ++ "\" " "log --template \"{latesttag}-{latesttagdistance}\n\" " - "--rev " ++ Ref, + "--rev " ++ rebar_utils:escape_chars(Ref), [{use_stdout, false}, {debug_abort_on_error, AbortMsg}]), Log = string:strip(LogString, both, $\n), @@ -121,7 +129,8 @@ get_tag_distance(Dir, Ref) -> get_branch_ref(Dir, Branch) -> AbortMsg = io_lib:format("Get branch ref of hg dependency failed in ~s", [Dir]), {ok, BranchRefString} = - rebar_utils:sh("hg -R '" ++ Dir ++ "' log --template \"{node}\n\" --rev " ++ Branch, + rebar_utils:sh("hg -R \"" ++ rebar_utils:escape_double_quotes(Dir) ++ + "\" log --template \"{node}\n\" --rev " ++ rebar_utils:escape_chars(Branch), [{use_stdout, false}, {debug_abort_on_error, AbortMsg}]), string:strip(BranchRefString, both, $\n). diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index d76fbda..74be7a6 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -142,7 +142,7 @@ copy_app_dirs(State, OldAppDir, AppDir) -> end, %% link to src_dirs to be adjacent to ebin is needed for R15 use of cover/xref - SrcDirs = rebar_dir:all_src_dirs(State, ["src"], ["test"]), + SrcDirs = rebar_dir:all_src_dirs(State, ["src"], []), [symlink_or_copy(OldAppDir, AppDir, Dir) || Dir <- ["priv", "include"] ++ SrcDirs]; false -> ok diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index 28c0ed6..41dd434 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -85,7 +85,8 @@ format_error({error_running_tests, Reason}) -> test_state(State) -> ErlOpts = rebar_state:get(State, eunit_compile_opts, []), TestOpts = safe_define_test_macro(ErlOpts), - first_files(State) ++ [{erl_opts, TestOpts}]. + TestDir = [{extra_src_dirs, ["test"]}], + first_files(State) ++ [{erl_opts, TestOpts ++ TestDir}]. safe_define_test_macro(Opts) -> %% defining a compile macro twice results in an exception so @@ -106,49 +107,38 @@ first_files(State) -> prepare_tests(State) -> {RawOpts, _} = rebar_state:command_parsed_args(State), - resolve_apps(State, RawOpts). + ok = maybe_cover_compile(State, RawOpts), + ProjectApps = project_apps(State), + resolve_apps(ProjectApps, RawOpts). -resolve_apps(State, RawOpts) -> +maybe_cover_compile(State, Opts) -> + State1 = case proplists:get_value(cover, Opts, false) of + true -> rebar_state:set(State, cover_enabled, true); + false -> State + end, + rebar_prv_cover:maybe_cover_compile(State1). + +resolve_apps(ProjectApps, RawOpts) -> case proplists:get_value(app, RawOpts) of - undefined -> resolve_suites(State, RawOpts); + undefined -> resolve_suites(ProjectApps, RawOpts); %% convert app name strings to `rebar_app_info` objects Apps -> AppNames = string:tokens(Apps, [$,]), - ProjectApps = project_apps(State), case filter_apps_by_name(AppNames, ProjectApps) of - {ok, TestApps} -> resolve_suites(State, TestApps, RawOpts); + {ok, TestApps} -> resolve_suites(TestApps, RawOpts); Error -> Error end end. -resolve_suites(State, RawOpts) -> resolve_suites(State, project_apps(State), RawOpts). - -resolve_suites(State, Apps, RawOpts) -> +resolve_suites(Apps, RawOpts) -> case proplists:get_value(suite, RawOpts) of - undefined -> compile_tests(State, Apps, all, RawOpts); + undefined -> test_set(Apps, all); Suites -> SuiteNames = string:tokens(Suites, [$,]), case filter_suites_by_apps(SuiteNames, Apps) of - {ok, S} -> compile_tests(State, Apps, S, RawOpts); + {ok, S} -> test_set(Apps, S); Error -> Error end end. -compile_tests(State, TestApps, Suites, RawOpts) -> - F = fun(AppInfo) -> - S = rebar_app_info:state_or_new(State, AppInfo), - ok = rebar_erlc_compiler:compile(replace_src_dirs(S), - ec_cnv:to_list(rebar_app_info:out_dir(AppInfo))) - end, - lists:foreach(F, TestApps), - ok = maybe_cover_compile(State, RawOpts), - {ok, test_set(TestApps, Suites)}. - -maybe_cover_compile(State, Opts) -> - State1 = case proplists:get_value(cover, Opts, false) of - true -> rebar_state:set(State, cover_enabled, true); - false -> State - end, - rebar_prv_cover:maybe_cover_compile(State1). - project_apps(State) -> filter_checkouts(rebar_state:project_apps(State)). @@ -215,20 +205,8 @@ app_modules([App|Rest], Acc) -> app_modules(Rest, NewAcc) end. -replace_src_dirs(State) -> - %% replace any `src_dirs` with the test dirs - ErlOpts = rebar_state:get(State, erl_opts, []), - StrippedOpts = filter_src_dirs(ErlOpts), - case rebar_dir:extra_src_dirs(State) of - [] -> rebar_state:set(State, erl_opts, [{src_dirs, ["test"]}|StrippedOpts]); - _ -> rebar_state:set(State, erl_opts, StrippedOpts) - end. - -filter_src_dirs(ErlOpts) -> - lists:filter(fun({src_dirs, _}) -> false; (_) -> true end, ErlOpts). - -test_set(Apps, all) -> set_apps(Apps, []); -test_set(_Apps, Suites) -> set_suites(Suites, []). +test_set(Apps, all) -> {ok, set_apps(Apps, [])}; +test_set(_Apps, Suites) -> {ok, set_suites(Suites, [])}. set_apps([], Acc) -> lists:reverse(Acc); set_apps([App|Rest], Acc) -> diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index ebdf0fe..6eb4f4b 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -57,7 +57,10 @@ tup_umerge/2, tup_sort/1, line_count/1, - set_httpc_options/0]). + set_httpc_options/0, + escape_chars/1, + escape_double_quotes/1, + escape_double_quotes_weak/1]). %% for internal use only -export([otp_release/0]). @@ -684,3 +687,15 @@ set_httpc_options(_, []) -> set_httpc_options(Scheme, Proxy) -> {ok, {_, _, Host, Port, _, _}} = http_uri:parse(Proxy), httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar). + +%% escape\ as\ a\ shell\? +escape_chars(Str) -> + re:replace(Str, "([ ()?`!$])", "\\\\&", [global, {return, list}]). + +%% "escape inside these" +escape_double_quotes(Str) -> + re:replace(Str, "([\"\\\\`!$*])", "\\\\&", [global, {return, list}]). + +%% "escape inside these" but allow * +escape_double_quotes_weak(Str) -> + re:replace(Str, "([\"\\\\`!$])", "\\\\&", [global, {return, list}]). |