diff --git a/src/rebar_raw_resource.erl b/src/rebar_raw_resource.erl index f74d16a..a8e6f52 100644 --- a/src/rebar_raw_resource.erl +++ b/src/rebar_raw_resource.erl @@ -36,11 +36,11 @@ % provider do/1, format_error/1, - init/1, + init/1, init/2, % rebar_resource - download/3, + download/3, download/4, lock/2, - make_vsn/1, + make_vsn/1, make_vsn/2, needs_update/2 ]). @@ -194,10 +194,26 @@ % download/3 is NOT called first if the dependency is already present, and % it's the only resource call that gets to see the rebar state. % +% Note: This arity is the pre-rebar3 3.7.0 format of this function. +% init(State) -> #mod_data{} = absorb_state(State), {'ok', rebar_state:add_resource(State, {?RTYPE, ?MODULE})}. +-spec init(Type :: rsrc_type(), + State :: rebar_state()) -> {'ok', rebar_state()}. +% +% Installs the resource handler, the provider itself does nothing. +% +% This gets called repeatedly, for each profile, and in each case we want +% to prime the process environment with any info we may need later, as +% download/3 is NOT called first if the dependency is already present, and +% it's the only resource call that gets to see the rebar state. +% +init(Type, State) -> + #mod_data{} = absorb_state(State), + {'ok', rebar_resource_v2:new(Type, ?MODULE, State)}. + -spec do(State :: rebar_state:t()) -> {'ok', rebar_state()}. % % Fulfills the `provider' contract, does nothing ... for now. @@ -225,11 +241,13 @@ format_error(Error) -> %% Resource API %% =================================================================== --spec download( - Dest :: rsrc_dir(), From :: this_spec(), State :: rebar_state()) - -> {'ok', term()} | rebar_err(). +-spec download(Dest :: rsrc_dir(), + From :: this_spec(), + State :: rebar_state()) + -> {'ok', term()} | rebar_err(). % % Download the specified resource using its underlying handler. +% Note: This arity is the pre-rebar3 3.7.0 format of this function. % download(Dest, {?RTYPE, Loc, #mod_ref{res = Res, ref = Ref, opt = Opts}}, State) -> @@ -254,42 +272,72 @@ download(Dest, {?RTYPE, Spec, Opts}, State) -> Err end. --spec lock(Path :: rsrc_dir(), Spec :: this_spec()) - -> rebar_lock() | no_return(). +-spec download(Dest :: rsrc_dir(), + AppInfo :: rebar_app_info:t(), + ResourceState :: term(), + State :: rebar_state()) + -> {'ok', term()} | rebar_err(). +% +% Download the specified resource using its underlying handler. +% +download(TmpDir, AppInfo, _ResourceState, RebarState) -> + download(TmpDir, rebar_app_info:source(AppInfo), RebarState). + +-spec lock(Path :: rsrc_dir(), + Spec :: this_spec()) + -> rebar_lock() | no_return(); + (AppInfo :: rebar_app_info:t(), + ResourceState :: term()) + -> rebar_lock() | no_return(). % % Pass through to the underlying resource handler. % Note that the callback doesn't allow an error tuple to be returned, so an % exception is our only option if we can't look up the mapping. % -lock(Path, {?RTYPE, Loc, #mod_ref{res = Res, ref = Prev} = Rec}) -> +%% pre-rebar3 3.7.0 format +lock(Path, Source) when not(erlang:is_tuple(Path)) -> + lock_(Path, Source); +%% rebar_resource_v2 format +lock(AppInfo, _ResourceState) -> + %% extract info for dir extract info for source + lock_(rebar_app_info:dir(AppInfo), rebar_app_info:source(AppInfo)). + +lock_(Path, {?RTYPE, Loc, #mod_ref{res = Res, ref = Prev} = Rec}) -> #mod_res{mod = Mod} = lookup_res(mod_data(), Res), {Res, Loc, Ref} = Mod:lock(Path, {Res, Loc, Prev}), {?RTYPE, Loc, Rec#mod_ref{ref = Ref}}; -lock(Path, {?RTYPE, Spec}) -> - lock(Path, {?RTYPE, Spec, []}); +lock_(Path, {?RTYPE, Spec}) -> + lock_(Path, {?RTYPE, Spec, []}); -lock(Path, {?RTYPE, Spec, Opts}) -> +lock_(Path, {?RTYPE, Spec, Opts}) -> {Res, _} = parse_ext_spec(Spec), #mod_res{mod = Mod} = lookup_res(mod_data(), Res), {Res, Loc, Ref} = Mod:lock(Path, Spec), {?RTYPE, Loc, #mod_ref{res = Res, ref = Ref, opt = Opts}}. --spec needs_update(Path :: rsrc_dir(), Spec :: this_spec()) +-spec needs_update(Path :: rsrc_dir(), SpecOrResourceState :: this_spec()) -> boolean() | no_return(). % % Pass through to the underlying resource handler. % Note that the callback doesn't allow an error tuple to be returned, so an % exception is our only option if we can't look up the mapping. % -needs_update(Path, {?RTYPE, Loc, #mod_ref{res = Res, ref = Ref}}) -> +%% pre-rebar3 3.7.0 format +needs_update(Dir, {_Type, _Path, _Ref} = Spec) -> + needs_update_(Dir, Spec); +%% rebar_resource_v2 compatible format +needs_update(AppInfo, _ResourceState) -> + needs_update_(rebar_app_info:dir(AppInfo), rebar_app_info:source(AppInfo)). + +needs_update_(Path, {?RTYPE, Loc, #mod_ref{res = Res, ref = Ref}}) -> #mod_res{mod = Mod} = lookup_res(mod_data(), Res), Mod:needs_update(Path, {Res, Loc, Ref}); -needs_update(Path, {?RTYPE, Spec, _}) -> - needs_update(Path, {?RTYPE, Spec}); +needs_update_(Path, {?RTYPE, Spec, _}) -> + needs_update_(Path, {?RTYPE, Spec}); -needs_update(Path, {?RTYPE, Spec}) -> +needs_update_(Path, {?RTYPE, Spec}) -> {Res, _} = parse_ext_spec(Spec), #mod_res{mod = Mod} = lookup_res(mod_data(), Res), Mod:needs_update(Path, Spec). @@ -306,6 +354,16 @@ make_vsn(Path) -> #mod_res{mod = Mod} = lookup_res(Data, Res), Mod:make_vsn(Path). +-spec make_vsn(Path :: rsrc_dir(), + State :: rebar_state()) + -> rebar_vsn() | {'error', string()} | no_return(). +% +% Pass through to the underlying resource handler. +% The weird error tuple spec comes from the rebar_resource behavior. +% +make_vsn(Dir, _ResourceState) -> + make_vsn(Dir). + %% =================================================================== %% Internal %% ===================================================================