diff --git a/bootstrap b/bootstrap index 4564ae8ff..96b4387c5 100755 --- a/bootstrap +++ b/bootstrap @@ -2,14 +2,25 @@ %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et -main(_) -> +main(Args) -> + case lists:member("--offline", Args) of + true -> + os:putenv("REBAR_OFFLINE", "1"); + false -> + ok + end, ensure_app(crypto), ensure_app(asn1), ensure_app(public_key), - ensure_app(ssl), - inets:start(), - inets:start(httpc, [{profile, rebar}]), - set_httpc_options(), + case os:getenv("REBAR_OFFLINE") of + "1" -> + ok; + _ -> + ensure_app(ssl), + inets:start(), + inets:start(httpc, [{profile, rebar}]), + set_httpc_options() + end, %% Clear directories for builds since bootstrapping may require %% a changed structure from an older one @@ -117,6 +128,14 @@ extract(Binary) -> {ok, Contents}. request(Url) -> + case os:getenv("REBAR_OFFLINE") of + "1" -> + {error, {offline, Url}}; + _ -> + request_online(Url) + end. + +request_online(Url) -> HttpOptions = [{relaxed, true} | get_proxy_auth()], case httpc:request(get, {Url, []}, diff --git a/src/rebar3.erl b/src/rebar3.erl index a0b9266f5..3e80ea0c5 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -177,17 +177,27 @@ run_aux(State, RawArgs) -> State9 = rebar_state:default(State8, rebar_state:opts(State8)), {Task, Args} = parse_args(RawArgs), + Offline = case lists:member("--offline", Args) of + true -> + %% We store this redundantly in env, because some APIs + %% don't get a state. + os:putenv("REBAR_OFFLINE", "1"), + true; + false -> + os:getenv("REBAR_OFFLINE") =:= "1" + end, + State10 = rebar_state:set(State9, offline, Offline), - State10 = rebar_state:code_paths(State9, default, code:get_path()), + State11 = rebar_state:code_paths(State10, default, code:get_path()), - case rebar_core:init_command(rebar_state:command_args(State10, Args), Task) of - {ok, State11} -> + case rebar_core:init_command(rebar_state:command_args(State11, Args), Task) of + {ok, State12} -> case rebar_state:get(State11, caller, command_line) of api -> rebar_paths:unset_paths([deps, plugins], State11), - {ok, State11}; + {ok, State12}; _ -> - {ok, State11} + {ok, State12} end; Other -> Other @@ -377,9 +387,14 @@ start_and_load_apps(Caller) -> ensure_running(crypto, Caller), ensure_running(asn1, Caller), ensure_running(public_key, Caller), - ensure_running(ssl, Caller), - ensure_running(inets, Caller), - inets:start(httpc, [{profile, rebar}]). + case os:getenv("REBAR_OFFLINE") of + "1" -> + ok; + _ -> + ensure_running(ssl, Caller), + ensure_running(inets, Caller), + inets:start(httpc, [{profile, rebar}]) + end. %% @doc Make sure a required app is running, or display an error message %% and abort if there's a problem. diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl index d32a42312..28753a308 100644 --- a/src/rebar_fetch.erl +++ b/src/rebar_fetch.erl @@ -50,6 +50,14 @@ download_source(AppInfo, State) -> end. download_source_(AppInfo, State) -> + case rebar_state:get(State, offline, false) of + true -> + {error, {?MODULE, offline}}; + false -> + download_source_online(AppInfo, State) + end. + +download_source_online(AppInfo, State) -> AppDir = rebar_app_info:dir(AppInfo), TmpDir = ec_file:insecure_mkdtemp(), AppDir1 = rebar_utils:to_list(AppDir), @@ -68,6 +76,17 @@ download_source_(AppInfo, State) -> -spec needs_update(rebar_app_info:t(), rebar_state:t()) -> boolean() | {error, string()}. needs_update(AppInfo, State) -> + case rebar_state:get(State, offline, false) of + true -> + ?DEBUG("Can't check if dependency needs updates in offline mode", []), + false; + false -> + needs_update_online(AppInfo, State) + end. + +-spec needs_update_online(rebar_app_info:t(), rebar_state:t()) + -> boolean() | {error, string()}. +needs_update_online(AppInfo, State) -> try rebar_resource_v2:needs_update(AppInfo, State) catch diff --git a/src/rebar_httpc_adapter.erl b/src/rebar_httpc_adapter.erl index b173cf6b3..26318d1ba 100644 --- a/src/rebar_httpc_adapter.erl +++ b/src/rebar_httpc_adapter.erl @@ -9,6 +9,18 @@ %%==================================================================== request(Method, URI, ReqHeaders, Body, AdapterConfig) -> + case os:getenv("REBAR_OFFLINE") of + "1" -> + {error, {offline, URI}}; + _ -> + request_online(Method, URI, ReqHeaders, Body, AdapterConfig) + end. + +%%==================================================================== +%% Internal functions +%%==================================================================== + +request_online(Method, URI, ReqHeaders, Body, AdapterConfig) -> Profile = maps:get(profile, AdapterConfig, default), Request = build_request(URI, ReqHeaders, Body), SSLOpts = [{ssl, rebar_utils:ssl_opts(URI)}], @@ -19,10 +31,6 @@ request(Method, URI, ReqHeaders, Body, AdapterConfig) -> {error, Reason} -> {error, Reason} end. -%%==================================================================== -%% Internal functions -%%==================================================================== - build_request(URI, ReqHeaders, Body) -> build_request2(binary_to_list(URI), dump_headers(ReqHeaders), Body). diff --git a/src/rebar_prv_local_upgrade.erl b/src/rebar_prv_local_upgrade.erl index 8f0d3a453..74d198da6 100644 --- a/src/rebar_prv_local_upgrade.erl +++ b/src/rebar_prv_local_upgrade.erl @@ -120,6 +120,19 @@ etag(Path) -> ETag :: false | string(), Res :: 'error' | {ok, cached} | {ok, any(), string()}. request(Url, ETag) -> + case os:getenv("REBAR_OFFLINE") of + "1" -> + ?DEBUG("Rebar is in offline mode", []), + error; + _ -> + request_online(Url, ETag) + end. + +-spec request_online(Url, ETag) -> Res when + Url :: string(), + ETag :: false | string(), + Res :: 'error' | {ok, cached} | {ok, any(), string()}. +request_online(Url, ETag) -> HttpOptions = [{ssl, rebar_utils:ssl_opts(Url)}, {relaxed, true} | rebar_utils:get_proxy_auth()], case httpc:request(get, {Url, [{"if-none-match", "\"" ++ ETag ++ "\""}