summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2015-05-22 19:45:48 -0400
committerFred Hebert <mononcqc@ferd.ca>2015-05-22 19:45:48 -0400
commitb4786b804c8b31a220e9daea753bd0ec3f7a62dd (patch)
tree31404932cbb3e220f99c3510e49ff0a3576fb578
parent5f577e2ab15d0aa3b6650f4e3d1ee086be3dc736 (diff)
parente45c67b023e310bd60de88f07f9429d66d18d4b0 (diff)
Merge pull request #471 from tsloughter/master
fall back to .app.src file if .app file fails to parse
-rw-r--r--src/rebar_app_discover.erl115
-rw-r--r--src/rebar_digraph.erl8
-rw-r--r--src/rebar_prv_install_deps.erl14
-rw-r--r--test/mock_pkg_resource.erl5
4 files changed, 78 insertions, 64 deletions
diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl
index 34310c7..e2ef179 100644
--- a/src/rebar_app_discover.erl
+++ b/src/rebar_app_discover.erl
@@ -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}}).
diff --git a/src/rebar_digraph.erl b/src/rebar_digraph.erl
index 9e10d49..d52a811 100644
--- a/src/rebar_digraph.erl
+++ b/src/rebar_digraph.erl
@@ -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).
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index cdc008c..80fdbc3 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -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(
diff --git a/test/mock_pkg_resource.erl b/test/mock_pkg_resource.erl
index e94ea93..9ed0962 100644
--- a/test/mock_pkg_resource.erl
+++ b/test/mock_pkg_resource.erl
@@ -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}