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
-~----------~----~----~----~------~----~------~--~---

Reply via email to