Mikael, Whats the goal here? Would you mind amending the patch with a bit of description around the reason?
Btw, thanks a million I really appreciate the help. eric On Sun, Jan 18, 2009 at 4:00 AM, Mikael Magnusson <[email protected]> wrote: > > From: Mikael Magnusson <[email protected]> > > Signed-off-by: Mikael Magnusson <[email protected]> > --- > server/sinan/src/sin_resolver.erl | 344 > +++++++++++++++++++++++++++++++++++++ > 1 files changed, 344 insertions(+), 0 deletions(-) > create mode 100644 server/sinan/src/sin_resolver.erl > > diff --git a/server/sinan/src/sin_resolver.erl > b/server/sinan/src/sin_resolver.erl > new file mode 100644 > index 0000000..203bb9a > --- /dev/null > +++ b/server/sinan/src/sin_resolver.erl > @@ -0,0 +1,344 @@ > +%%%------------------------------------------------------------------- > +%%% Copyright (c) 2007 Eric Merritt, Martin Logan > +%%% > +%%% Permission is hereby granted, free of charge, to any > +%%% person obtaining a copy of this software and associated > +%%% documentation files (the "Software"), to deal in the > +%%% Software without restriction, including without limitation > +%%% the rights to use, copy, modify, merge, publish, distribute, > +%%% sublicense, and/or sell copies of the Software, and to permit > +%%% persons to whom the Software is furnished to do so, subject to > +%%% the following conditions: > +%%% > +%%% The above copyright notice and this permission notice shall > +%%% be included in all copies or substantial portions of the Software. > +%%% > +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > +%%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES > +%%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > +%%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT > +%%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, > +%%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > +%%% OTHER DEALINGS IN THE SOFTWARE. > +%%%------------------------------------------------------------------- > +%%% @doc > +%%% Resolves individual items for the dependency engine. > +%%% @copyright Erlware 2007 > +%%% @end > +%%%------------------------------------------------------------------- > +-module(sin_resolver). > + > +-include("eunit.hrl"). > + > +%% API > +-export([package_versions/3, > + package_dependencies/4, > + find_package_location/4, > + gather_version_info/2]). > + > + > + > +%%==================================================================== > +%% API > +%%==================================================================== > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the list of versions available for the specified package. > +%% > +%% @spec (Prefix, ErtsVersion, Package) -> VersionList > +%% @end > +%%-------------------------------------------------------------------- > +package_versions(Prefix, ErtsVersion, Package) when is_atom(Package) -> > + VList = gather_version_info(Prefix, ErtsVersion), > + get_package_versions(Package, > + Prefix, > + VList, > + []); > +package_versions(_, _, _) -> > + throw({error, "Package name must be an atom"}). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the list of dependencies for the specified package and the > +%% specified version. > +%% > +%% @spec (Prefix, ErtsVersion, Package, Version) -> Deps | Error > +%% @end > +%%-------------------------------------------------------------------- > +package_dependencies(Prefix, ErtsVersion, Package, Version) -> > + VList = gather_version_info(Prefix, ErtsVersion), > + NPackage = atom_to_list(Package), > + NDeps = get_package_dependencies(NPackage, > + Version, > + Prefix, > + VList), > + NDeps. > + > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the dependencies for a package and version. > +%% > +%% @spec (Package, Version, Prefix, Versions) -> Location > +%% @end > +%%-------------------------------------------------------------------- > +find_package_location(Prefix, ErtsVersion, Package, Version) -> > + VList = gather_version_info(Prefix, ErtsVersion), > + find_package_location_across_versions(Package, Version, Prefix, VList). > + > + > +%%==================================================================== > +%%% Internal functions > +%%==================================================================== > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the list of subdirectories for the current directory > +%% > +%% @spec (Dir) -> ListOfDirs > +%% @end > +%%-------------------------------------------------------------------- > +list_subdirectories(Dir) -> > + lists:filter(fun(X) -> filelib:is_dir(X) end, > + filelib:wildcard(Dir ++ "/*")). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the dependencies for a package and version. > +%% > +%% @spec (Package, Version, Prefix, Versions) -> Location > +%% @end > +%%-------------------------------------------------------------------- > +find_package_location_across_versions(Package, Version, > + Prefix, [ErtsVersion | ErtsVersions]) -> > + PackageName = lists:flatten([Package, "-", Version]), > + FileName = filename:join([Prefix, "packages", ErtsVersion, > + "lib", PackageName]), > + case filelib:is_dir(FileName) of > + true -> > + FileName; > + false -> > + find_package_location_across_versions(Package, Version, > + Prefix, ErtsVersions) > + end; > +find_package_location_across_versions(_, _, _, []) -> > + throw({error, "Unable to find location for package"}). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get all versions that share the same major.minor version > +%% with the current erts. Thats erts version, not app version > +%% > +%% @spec gather_version_info(Prefix, ErtsVersion) -> ErtsVersions > +%% @end > +%%-------------------------------------------------------------------- > +gather_version_info(Prefix, ErtsVersion) -> > + ErtsVersions = lists:reverse( > + lists:sort( > + lists:map(fun(File) -> > + filename:basename(File) > + end, > + list_subdirectories( > + filename:join([Prefix, "packages"]))))), > + NewErtsVersion = get_major_minor(ErtsVersion, 0, []), > + lists:filter(fun(X) -> > + starts_with(NewErtsVersion, X) > + end, > + ErtsVersions). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Check that list1 is the same as the first part of list2 > +%% > +%% @spec (List1, List2) -> true | false > +%% @end > +%%-------------------------------------------------------------------- > +starts_with([C1 | Rest1], [C1 | Rest2]) -> > + starts_with(Rest1, Rest2); > +starts_with([], _) -> > + true; > +starts_with(_, _) -> > + false. > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the major.minor version from version string. > +%% > +%% @spec (Name, Count, Acc) -> MajorMinor > +%% @end > +%%-------------------------------------------------------------------- > +get_major_minor([$. | _], 1, Acc) -> > + lists:reverse(Acc); > +get_major_minor([$. | Rest], 0, Acc) -> > + get_major_minor(Rest, 1, [$. | Acc]); > +get_major_minor([Head | Rest], Count, Acc) -> > + get_major_minor(Rest, Count, [Head | Acc]); > +get_major_minor([], _, Acc) -> > + lists:reverse(Acc). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the version from an app-version > +%% > +%% @spec (Name) -> Version > +%% @end > +%%-------------------------------------------------------------------- > +get_version([$- | Rest]) -> > + Rest; > +get_version([_ | Rest]) -> > + get_version(Rest); > +get_version([]) -> > + throw({error, "Unable to find package version"}). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Acc is a set. It this just makes sure only one entry is in the set > +%% > +%% @spec (Name, In, Acc) -> NewAcc > +%% @end > +%%-------------------------------------------------------------------- > +add_to_acc([Name | Rest1] , [Name | _], Acc) -> > + add_to_acc(Rest1, Acc, Acc); > +add_to_acc(All, [_ | Rest], Acc) -> > + add_to_acc(All, Rest, Acc); > +add_to_acc([Name | Rest], [], Acc) -> > + NewAcc = [Name | Acc], > + add_to_acc(Rest, NewAcc, NewAcc); > +add_to_acc([], [], Acc) -> > + lists:reverse(Acc). > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get all the versions for a package, search across all > +%% relavent major/minor versions. > +%% > +%% @spec (Package, Prefix, Versions, Acc) -> Versions > +%% @end > +%%-------------------------------------------------------------------- > +get_package_versions(Package, Prefix, [ErtsVersion | ErtsVersions], Acc) -> > + FileName = filename:join([Prefix, "packages", ErtsVersion, > + "lib"]), > + AppVersions = lists:filter(fun(X) -> > + starts_with(atom_to_list(Package) > + ++ "-", > filename:basename(X)) > + end, > + list_subdirectories(FileName)), > + Versions = lists:map(fun(X) -> > + get_version(X) > + end, > + AppVersions), > + get_package_versions(Package, Prefix, ErtsVersions, > + add_to_acc(Versions, Acc, Acc)); > +get_package_versions(_, _, [], Acc) -> > + Acc. > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the dependencies for a package and version. > +%% > +%% @spec (Package, Version, Prefix, Versions) -> Deps > +%% @end > +%%-------------------------------------------------------------------- > +get_package_dependencies(Package, Version, Prefix, > + [ErtsVersion | ErtsVersions]) -> > + DotAppName = lists:flatten([Package, ".app"]), > + AppName = lists:flatten([Package, "-", Version]), > + case file:consult(filename:join([Prefix, "packages", > + ErtsVersion, "lib", AppName, > + "ebin", DotAppName])) of > + {ok, [Term]} -> > + handle_parse_output(Term); > + {error, _} -> > + get_package_dependencies(Package, Version, Prefix, > + [ErtsVersion | ErtsVersions]) > + end; > +get_package_dependencies(_, _, _, []) -> > + throw({error, "Unable to find dependencies for package"}). > + > + > + > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% get the version the deps and the versioned deps from an *.app > +%% term. > +%% > +%% @spec handle_parse_output(AppTerm) -> {Vsn, VersionedDeps, Deps} | > {error, Reason} > +%% @end > +%%-------------------------------------------------------------------- > +handle_parse_output({application, _, Ops}) -> > + lists:umerge(lists:sort(get_deps(Ops)), > + lists:sort(get_ideps(Ops))); > +handle_parse_output(_) -> > + throw({error, "Invalid dependency info"}). > + > + > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the list of non-versioned dependencies from the oplist. This > +%% is specifed in the applications entry. > +%% @spec get_deps(OpList) -> Dependencies > +%% @end > +%% @private > +%%-------------------------------------------------------------------- > +get_deps([{applications, List} | _T]) -> > + List; > +get_deps([_ | T]) -> > + get_deps(T); > +get_deps([]) -> > + []. > + > + > +%%-------------------------------------------------------------------- > +%% @doc > +%% Get the list of included applications. > +%% @spec get_ideps(OpList) -> IncludedDependencies > +%% @end > +%% @private > +%%-------------------------------------------------------------------- > +get_ideps([{included_applications, List} | _T]) -> > + List; > +get_ideps([_ | T]) -> > + get_ideps(T); > +get_ideps([]) -> > + []. > + > +%%==================================================================== > +%% tests > +%%==================================================================== > +handle_parse_output_test() -> > + Data = {application, testapp, > + [{vsn, "0.1.0"}, > + {description, "test test test"}, > + {versioned_dependencies, > + [{app1, "0.1.0"}, {app2, "0.33.1", gte}, > + {app3, "33.11.3"}]}, > + {applications, [app1, app2, app3, app4, app5]}]}, > + ?assertMatch([{app3, [33, 11, 3]}, {app2, [0, 33, 1],gte}, > + {app1, [0, 1, 0]}, app5, app4], > + handle_parse_output(Data)). > + > +starts_with_test() -> > + ?assertMatch(true, starts_with("onetwo", "onetwothree")), > + ?assertMatch(false, starts_with("onetwo", "threetwoone")). > + > +get_major_minor_test() -> > + ?assertMatch("5.6", get_major_minor("5.6.3", 0, [])), > + ?assertMatch("5.5", get_major_minor("5.5.5", 0, [])). > + > +get_version_test() -> > + ?assertMatch("1.0", get_version("sinan-1.0")), > + ?assertMatch("1.3.2.2", get_version("bah-1.3.2.2")). > + > +add_to_acc_test() -> > + Start = ["one", "two", "one", "three", "four", "two"], > + ?assertMatch(["one", "two", "three", "four"], add_to_acc(Start, [], [])). > + > +gather_version_info_test() -> > + Prefix = "/usr/local/erlware", > + Version = "5.6.3", > + ?assertMatch([Version], gather_version_info(Prefix, Version)). > + > +get_package_versions_test() -> > + ?assertMatch(["10.0.1"], get_package_versions(sinan, > "/usr/local/erlware", ["5.6.3"], [])). > -- > 1.5.6.3 > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "erlware-dev" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/erlware-dev?hl=en -~----------~----~----~----~------~----~------~--~---
