diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2015-05-22 19:45:48 -0400 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2015-05-22 19:45:48 -0400 |
commit | b4786b804c8b31a220e9daea753bd0ec3f7a62dd (patch) | |
tree | 31404932cbb3e220f99c3510e49ff0a3576fb578 | |
parent | 5f577e2ab15d0aa3b6650f4e3d1ee086be3dc736 (diff) | |
parent | e45c67b023e310bd60de88f07f9429d66d18d4b0 (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.erl | 115 | ||||
-rw-r--r-- | src/rebar_digraph.erl | 8 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 14 | ||||
-rw-r--r-- | test/mock_pkg_resource.erl | 5 |
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} |