Browse Source

Merge pull request #471 from tsloughter/master

fall back to .app.src file if .app file fails to parse
pull/472/head
Fred Hebert 10 years ago
parent
commit
b4786b804c
4 changed files with 78 additions and 64 deletions
  1. +62
    -53
      src/rebar_app_discover.erl
  2. +6
    -2
      src/rebar_digraph.erl
  3. +8
    -6
      src/rebar_prv_install_deps.erl
  4. +2
    -3
      test/mock_pkg_resource.erl

+ 62
- 53
src/rebar_app_discover.erl View File

@ -7,6 +7,7 @@
find_apps/2,
find_app/2]).
-include("rebar.hrl").
-include_lib("providers/include/providers.hrl").
do(State, LibDirs) ->
@ -123,59 +124,8 @@ find_apps(LibDirs, Validate) ->
find_app(AppDir, Validate) ->
AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])),
AppSrcFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src"])),
case AppFile of
[File] ->
AppInfo = create_app_info(AppDir, File),
AppInfo1 = rebar_app_info:app_file(AppInfo, File),
AppInfo2 = case AppSrcFile of
[F] ->
rebar_app_info:app_file_src(AppInfo1, F);
[] ->
AppInfo1;
Other when is_list(Other) ->
throw({error, {multiple_app_files, Other}})
end,
case Validate of
valid ->
case rebar_app_utils:validate_application_info(AppInfo2) of
true ->
{true, AppInfo2};
_ ->
false
end;
invalid ->
case rebar_app_utils:validate_application_info(AppInfo2) of
true ->
false;
_ ->
{true, AppInfo2}
end;
all ->
{true, AppInfo2}
end;
[] ->
case AppSrcFile of
[File] ->
case Validate of
V when V =:= invalid ; V =:= all ->
AppInfo = create_app_info(AppDir, File),
case AppInfo of
{error, Reason} ->
throw({error, {invalid_app_file, File, Reason}});
_ ->
{true, rebar_app_info:app_file_src(AppInfo, File)}
end;
valid ->
false
end;
[] ->
false;
Other when is_list(Other) ->
throw({error, {multiple_app_files, Other}})
end;
Other when is_list(Other) ->
throw({error, {multiple_app_files, Other}})
end.
AppInfo = try_handle_app_file(AppFile, AppDir, AppSrcFile, Validate),
AppInfo.
app_dir(AppFile) ->
filename:join(rebar_utils:droplast(filename:split(filename:dirname(AppFile)))).
@ -202,3 +152,62 @@ dedup([]) -> [];
dedup([A]) -> [A];
dedup([H,H|T]) -> dedup([H|T]);
dedup([H|T]) -> [H|dedup(T)].
%% Read in and parse the .app file if it is availabe. Do the same for
%% the .app.src file if it exists.
try_handle_app_file([], AppDir, AppSrcFile, Validate) ->
try_handle_app_src_file([], AppDir, AppSrcFile, Validate);
try_handle_app_file([File], AppDir, AppSrcFile, Validate) ->
try create_app_info(AppDir, File) of
AppInfo ->
AppInfo1 = rebar_app_info:app_file(AppInfo, File),
AppInfo2 = case AppSrcFile of
[F] ->
rebar_app_info:app_file_src(AppInfo1, F);
[] ->
AppInfo1;
Other when is_list(Other) ->
throw({error, {multiple_app_files, Other}})
end,
case Validate of
valid ->
case rebar_app_utils:validate_application_info(AppInfo2) of
true ->
{true, AppInfo2};
_ ->
false
end;
invalid ->
case rebar_app_utils:validate_application_info(AppInfo2) of
true ->
false;
_ ->
{true, AppInfo2}
end;
all ->
{true, AppInfo2}
end
catch
throw:{error, {Module, Reason}} ->
?DEBUG("Falling back to app.src file because .app failed: ~s", [Module:format_error(Reason)]),
try_handle_app_src_file(File, AppDir, AppSrcFile, Validate)
end;
try_handle_app_file(Other, _AppDir, _AppSrcFile, _Validate) ->
throw({error, {multiple_app_files, Other}}).
%% Read in the .app.src file if we aren't looking for a valid (already built) app
try_handle_app_src_file(_, _AppDir, [], _Validate) ->
false;
try_handle_app_src_file(_, _AppDir, _AppSrcFile, valid) ->
false;
try_handle_app_src_file(_, AppDir, [File], Validate) when Validate =:= invalid
; Validate =:= all ->
AppInfo = create_app_info(AppDir, File),
case AppInfo of
{error, Reason} ->
throw({error, {invalid_app_file, File, Reason}});
_ ->
{true, rebar_app_info:app_file_src(AppInfo, File)}
end;
try_handle_app_src_file(_, _AppDir, Other, _Validate) ->
throw({error, {multiple_app_files, Other}}).

+ 6
- 2
src/rebar_digraph.erl View File

@ -124,6 +124,10 @@ find_app_by_name(Name, Apps) ->
rebar_app_info:name(App) =:= Name
end, Apps).
%% The union of all entries in the applications list for an app and
%% the deps listed in its rebar.config is all deps that may be needed
%% for building the app.
all_apps_deps(App) ->
Applications = [atom_to_binary(X, utf8) || X <- rebar_app_info:applications(App)],
lists:usort(rebar_app_info:deps(App) ++ Applications).
Applications = lists:usort([atom_to_binary(X, utf8) || X <- rebar_app_info:applications(App)]),
Deps = lists:usort(lists:map(fun({Name, _}) -> Name; (Name) -> Name end, rebar_app_info:deps(App))),
lists:umerge(Deps, Applications).

+ 8
- 6
src/rebar_prv_install_deps.erl View File

@ -261,9 +261,7 @@ package_to_app(DepsDir, Packages, {Name, Vsn, Level}, IsLock, State) ->
false ->
throw(?PRV_ERROR({missing_package, Name, Vsn}))
end;
{ok, P} ->
PkgDeps = [{PkgName, PkgVsn}
|| {PkgName,PkgVsn} <- proplists:get_value(<<"deps">>, P, [])],
{ok, PkgDeps} ->
{ok, AppInfo} = rebar_app_info:new(Name, Vsn),
AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps),
AppInfo2 = rebar_app_info:dir(AppInfo1, filename:join([DepsDir, Name])),
@ -410,7 +408,7 @@ maybe_fetch(AppInfo, Profile, Upgrade, Seen, State) ->
case fetch_app(AppInfo, AppDir, State) of
true ->
maybe_symlink_default(State, Profile, AppDir, AppInfo),
{true, update_app_info(AppInfo)};
{true, update_app_info(AppDir, AppInfo)};
Other ->
{Other, AppInfo}
end;
@ -577,8 +575,12 @@ fetch_app(AppInfo, AppDir, State) ->
throw(Error)
end.
update_app_info(AppInfo) ->
AppDetails = rebar_app_info:app_details(AppInfo),
%% This is called after the dep has been downloaded and unpacked, if it hadn't been already.
%% So this is the first time for newly downloaded apps that its .app/.app.src data can
%% be read in an parsed.
update_app_info(AppDir, AppInfo) ->
{ok, Found} = rebar_app_info:discover(AppDir),
AppDetails = rebar_app_info:app_details(Found),
Applications = proplists:get_value(applications, AppDetails, []),
IncludedApplications = proplists:get_value(included_applications, AppDetails, []),
AppInfo1 = rebar_app_info:applications(

+ 2
- 3
test/mock_pkg_resource.erl View File

@ -151,15 +151,14 @@ find_parts([{AppName, Deps}|Rest], Skip, Acc) ->
true -> find_parts(Rest, Skip, Acc);
false ->
AccNew = dict:store(AppName,
[{<<"deps">>,Deps}, {<<"link">>,<<"undef">>}],
Deps,
Acc),
find_parts(Rest, Skip, AccNew)
end.
to_graph_parts(Dict) ->
LastUpdated = os:timestamp(),
dict:fold(fun(K,V,{Ks,Vs}) ->
{_,Deps} = lists:keyfind(<<"deps">>, 1, V),
dict:fold(fun(K,Deps,{Ks,Vs}) ->
{[{K,LastUpdated}|Ks],
[{K,{list_to_binary(atom_to_list(DK)), list_to_binary(DV)}}
|| {DK,DV} <- Deps] ++ Vs}

Loading…
Cancel
Save