---
 _build.cfg                      |    2 +-
 lib/ewlib/ebin/ewlib.app        |   18 +-
 lib/ewlib/src/ewl_file.erl      |  110 +++++++----
 lib/ewrepo/src/ewr_depends.erl  |   48 +++---
 lib/ewrepo/src/ewr_resolver.erl |  410 +++++++++++++++++++++++----------------
 5 files changed, 351 insertions(+), 237 deletions(-)

diff --git a/_build.cfg b/_build.cfg
index 7aad23e..5c1dace 100644
--- a/_build.cfg
+++ b/_build.cfg
@@ -1,6 +1,6 @@
 project : {
    name : erlware
-   vsn  : "0.5.0.0"
+   vsn  : "0.6.0.0"
 },
 
 repositories : ["http://repo.erlware.org/pub";],
diff --git a/lib/ewlib/ebin/ewlib.app b/lib/ewlib/ebin/ewlib.app
index 6f8e572..3653c32 100644
--- a/lib/ewlib/ebin/ewlib.app
+++ b/lib/ewlib/ebin/ewlib.app
@@ -1,15 +1,15 @@
 {application, ewlib,
  [{description, "Erlware support library"},
-  {vsn, "0.8.2.0"},
+  {vsn, "0.9.2.0"},
   {modules, [
-            ewl_talk, 
-            ewl_elwrap_h, 
-            ewl_get_opt, 
-            ewl_string_manip, 
-            ewl_file, 
-            ewl_config_diff, 
-            ewl_installed_paths, 
-            ewl_package_paths, 
+            ewl_talk,
+            ewl_elwrap_h,
+            ewl_get_opt,
+            ewl_string_manip,
+            ewl_file,
+            ewl_config_diff,
+            ewl_installed_paths,
+            ewl_package_paths,
             ewl_sinan_paths
            ]},
   {registered, []},
diff --git a/lib/ewlib/src/ewl_file.erl b/lib/ewlib/src/ewl_file.erl
index b328281..1e069dc 100644
--- a/lib/ewlib/src/ewl_file.erl
+++ b/lib/ewlib/src/ewl_file.erl
@@ -1,31 +1,32 @@
+
 %%%-------------------------------------------------------------------
 %%% Copyright (c) 2006 Erlware
 %%%
-%%% 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 
+%%% 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 
+%%% 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 
+%%% 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 
+%%% 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 
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 %%% OTHER DEALINGS IN THE SOFTWARE.
 %%%-------------------------------------------------------------------
-%%% @author  Martin J. Logan 
+%%% @author  Martin J. Logan
 %%%
 %%% @doc
-%%%  Functions to aid in common file system operations that are not supplied 
in the erlang stdlib. 
+%%%  Functions to aid in common file system operations that are not supplied 
in the erlang stdlib.
 %%% @end
 %%%-------------------------------------------------------------------
 -module(ewl_file).
@@ -43,7 +44,9 @@
         compress/2,
         uncompress/1,
         uncompress/2,
-        gsub_file/3
+        gsub_file/3,
+        file_exists/1,
+        list_subdirectories/1
         ]).
 
 %%--------------------------------------------------------------------
@@ -56,15 +59,44 @@
 %% External 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
+%%  Check to see if a file exists.
+%%
+%% @spec (FileName) -> true | false
+%% @end
+%%-------------------------------------------------------------------
+file_exists(FileName) ->
+    case file:read_file_info(FileName) of
+        {error, enoent} ->
+            false;
+        Error = {error, _} ->
+            throw(Error);
+        _ ->
+            true
+    end.
+
+
+%%--------------------------------------------------------------------
 %% @doc delete a non empty directory.
-%% @spec delete_dir(Path) -> ok 
+%% @spec delete_dir(Path) -> ok
 %% @end
 %%--------------------------------------------------------------------
 delete_dir(Path) ->
     case filelib:is_dir(Path) of
        false ->
            case filelib:is_file(Path) of
-               false -> 
+               false ->
                    case file:read_link_info(Path) of
                        {ok, LinkInfo} ->
                            %% XXX Exploiting the structure of a record, tisk, 
tisk, should probably include the proper .hrl file.
@@ -73,7 +105,7 @@ delete_dir(Path) ->
                        _ ->
                            error_logger:info_msg("delete_dir/1 file does not 
exist ~p~n", [Path]), ok
                    end;
-               true -> 
+               true ->
                    ok = file:delete(Path)
            end;
        true ->
@@ -95,7 +127,7 @@ copy_dir(From, To) ->
                true  -> ok;
                false -> ok = file:make_dir(To)
            end,
-           lists:foreach(fun(ChildFrom) -> 
+           lists:foreach(fun(ChildFrom) ->
                                  copy_dir(ChildFrom, lists:flatten([To, "/", 
filename:basename(ChildFrom)]))
                          end, filelib:wildcard(From ++ "/*"))
     end.
@@ -121,11 +153,11 @@ create_tmp_dir(Prefix) ->
        ok    -> {ok, TmpDirPath};
        Error -> Error
     end.
-            
+
 
 %%-------------------------------------------------------------------
 %% @doc
-%% Makes a directory including parent dirs if they are missing. 
+%% Makes a directory including parent dirs if they are missing.
 %% @spec mkdir_p(Path) -> ok | exit()
 %% @end
 %%-------------------------------------------------------------------
@@ -134,7 +166,7 @@ mkdir_p(Path) ->
        "win32" ->
            filelib:ensure_dir(lists:flatten([filename:absname(Path), "\\"]));
        _SysArch ->
-           filelib:ensure_dir(lists:flatten([filename:absname(Path), "/"]))  
+           filelib:ensure_dir(lists:flatten([filename:absname(Path), "/"]))
     end.
 
 %%-------------------------------------------------------------------
@@ -143,7 +175,7 @@ mkdir_p(Path) ->
 %% are very straight forward. Indicate where you want the tar file
 %% to be placed and indicate what file you want to tar up. This will
 %% do that. It will tar the target file as if it was doing it from
-%% directory that contains it. 
+%% directory that contains it.
 %% <pre>
 %% Variables:
 %%  TarFilePath - The name or path to the file to be produced as a result of 
the tar command.
@@ -157,7 +189,7 @@ mkdir_p(Path) ->
 %% @end
 %%-------------------------------------------------------------------
 compress(TarFilePath, TargetFilePath) ->
-    %% Wrapping this just in case we have to go back to os specific code - I 
am tired of changing this all over the place :) 
+    %% Wrapping this just in case we have to go back to os specific code - I 
am tired of changing this all over the place :)
     TarFileName = filename:basename(TarFilePath),
     TargetFileName = filename:basename(TargetFilePath),
 
@@ -166,9 +198,9 @@ compress(TarFilePath, TargetFilePath) ->
                  file:rename(TarFileName, TarFilePath)
          end,
     run_in_location(Fun, filename:dirname(TargetFilePath)).
-    
+
 %%-------------------------------------------------------------------
-%% @doc Uncompress a file or directory using the native os compression system. 
For linux/unix it is tar. 
+%% @doc Uncompress a file or directory using the native os compression system. 
For linux/unix it is tar.
 %% <pre>
 %% Variables:
 %%  TarFileName - The path and name of the tar file to be untarred.
@@ -178,7 +210,7 @@ compress(TarFilePath, TargetFilePath) ->
 %% @end
 %%-------------------------------------------------------------------
 uncompress(TarFilePath, TargetDirPath) ->
-    %% Wrapping this just in case we have to go back to os specific code - I 
am tired of changing this all over the place :) 
+    %% Wrapping this just in case we have to go back to os specific code - I 
am tired of changing this all over the place :)
     TarFileName = filename:basename(TarFilePath),
     RelocatedTarFilePath = filename:join(TargetDirPath, TarFileName),
     case TarFilePath == RelocatedTarFilePath of
@@ -194,15 +226,15 @@ uncompress(TarFilePath, TargetDirPath) ->
                  end
          end,
     run_in_location(Fun, TargetDirPath).
-    
-    
+
+
 %% @spec uncompress(TarFilePath::string()) -> ok | exit()
-%% @equiv uncompress(TarFilePath, CurrentWorkingDirectory) 
+%% @equiv uncompress(TarFilePath, CurrentWorkingDirectory)
 uncompress(TarFilePath) ->
     {ok, CWD} = file:get_cwd(),
     uncompress(TarFilePath, CWD).
-    
-    
+
+
 %%-------------------------------------------------------------------
 %% @doc
 %%  Finds files and directories that match the regexp supplied in the 
TargetPattern regexp.
@@ -215,18 +247,18 @@ find([], _) ->
 find(FromDir, TargetPattern) ->
     case filelib:is_dir(FromDir) of
        false ->
-           case regexp:match(FromDir, TargetPattern) of 
-               {match, _, _} -> [FromDir]; 
+           case regexp:match(FromDir, TargetPattern) of
+               {match, _, _} -> [FromDir];
                _             -> []
            end;
        true ->
-           FoundDir = case regexp:match(FromDir, TargetPattern) of 
-               {match, _, _} -> [FromDir]; 
+           FoundDir = case regexp:match(FromDir, TargetPattern) of
+               {match, _, _} -> [FromDir];
                _             -> []
            end,
-           List = lists:foldl(fun(CheckFromDir, Acc) when CheckFromDir == 
FromDir -> 
+           List = lists:foldl(fun(CheckFromDir, Acc) when CheckFromDir == 
FromDir ->
                                Acc;
-                          (ChildFromDir, Acc) -> 
+                          (ChildFromDir, Acc) ->
                                case find(ChildFromDir, TargetPattern) of
                                    []  -> Acc;
                                    Res -> Res ++ Acc
@@ -258,7 +290,7 @@ gsub_file(FilePath, RegExp, New) ->
     {ok, BinaryContents} =file:read_file(FilePath),
     Contents = binary_to_list(BinaryContents),
     case regexp:gsub(Contents, RegExp, New) of
-       {ok, NewContents, RepCount} -> 
+       {ok, NewContents, RepCount} ->
            {ok, IOD} = file:open(FilePath, [write]),
            ok = io:fwrite(IOD, "~s", [NewContents]),
            {ok, RepCount};
@@ -278,7 +310,7 @@ gsub_file(FilePath, RegExp, New) ->
 %%--------------------------------------------------------------------
 ensure_leading_slash(String) ->
     lists:flatten(["/", string:strip(String, left, $/)]).
-    
+
 %%--------------------------------------------------------------------
 %% @private
 %% @doc ensure that the string provided does not contain a trailing slash
diff --git a/lib/ewrepo/src/ewr_depends.erl b/lib/ewrepo/src/ewr_depends.erl
index 8d0cb2d..adea802 100644
--- a/lib/ewrepo/src/ewr_depends.erl
+++ b/lib/ewrepo/src/ewr_depends.erl
@@ -1,31 +1,31 @@
 %%%-------------------------------------------------------------------
 %%% Copyright (c) 2006 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 
+%%% 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 
+%%% 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 
+%%% 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 
+%%% 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 
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 %%% OTHER DEALINGS IN THE SOFTWARE.
 %%%-------------------------------------------------------------------
 %%% @author Eric Merritt
 %%% @copyright 2006 Erlware
 %%% @doc
-%%%   Figures out the dependencies for the application, via teh 
+%%%   Figures out the dependencies for the application, via teh
 %%%   ewr_deps_engine.
 %%% @end
 %%%-------------------------------------------------------------------
@@ -36,28 +36,28 @@
 
 %% API
 -export([
-         check_project_dependencies/3
+         check_project_dependencies/4
        ]).
 
 %%====================================================================
 %% API
 %%====================================================================
 %%--------------------------------------------------------------------
-%% @doc 
-%%  Resolves dependencies using the information provided by Urls. 
-%% 
+%% @doc
+%%  Resolves dependencies using the information provided by Urls.
+%%
 %% DepInformation must be in the form of [{App, Vsn, {BareDeps, 
VersionedDeps}}, ...].
-%% Given that information it will return the correct list of 
+%% Given that information it will return the correct list of
 %% dependencies.
 %%
 %% @spec check_project_dependencies(Urls, DepInformation, SupplimentalDeps) -> 
Deps
 %% @end
 %%--------------------------------------------------------------------
-check_project_dependencies(Urls, DepInformation, SupplimentalDeps) ->
-    {Transformed, Apps, VList} = 
+check_project_dependencies(Prefix, Erts, DepInformation, SupplimentalDeps) ->
+    {Transformed, Apps, VList} =
         lists:foldl(fun preformat_version_data/2, {[], [], []}, 
DepInformation),
-    ewr_resolver:start_link(Urls, Transformed, VList),
-    Edps = ewr_deps_engine:init(fun ewr_resolver:package_versions/1, 
+    ewr_resolver:start_link(Prefix, Erts, Transformed, VList),
+    Edps = ewr_deps_engine:init(fun ewr_resolver:package_versions/1,
                                fun ewr_resolver:package_dependencies/2),
     case ewr_deps_engine:deps(Edps, SupplimentalDeps ++ Apps) of
         fail ->
@@ -76,8 +76,8 @@ check_project_dependencies(Urls, DepInformation, 
SupplimentalDeps) ->
 %%====================================================================
 
 %%--------------------------------------------------------------------
-%% @doc 
-%%  Parse the app description into a format consumable by the 
+%% @doc
+%%  Parse the app description into a format consumable by the
 %%  deps engine.
 %% @spec preformat_version_data(AppInfo, Acc) -> {Deps, Pkg, Vsns}
 %% @end
@@ -90,7 +90,7 @@ preformat_version_data({App, Vsn, {ADeps, VDeps}}, {DepList, 
AppList, VsnList})
     {[{Key, NDeps} | DepList], [Key | AppList], [VKey | VsnList]}.
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Parse the version string in versioned dependencies into something
 %%  usable by the system.
 %% @spec parse_vdeps(undefined, Acc) -> Deps
diff --git a/lib/ewrepo/src/ewr_resolver.erl b/lib/ewrepo/src/ewr_resolver.erl
index 5c5a290..5152a3b 100644
--- a/lib/ewrepo/src/ewr_resolver.erl
+++ b/lib/ewrepo/src/ewr_resolver.erl
@@ -1,25 +1,25 @@
 %%%-------------------------------------------------------------------
 %%% 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 
+%%% 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 
+%%% 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 
+%%% 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 
+%%% 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 
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 %%% OTHER DEALINGS IN THE SOFTWARE.
 %%%-------------------------------------------------------------------
 %%% @doc
@@ -34,12 +34,13 @@
 -include("eunit.hrl").
 
 
-
 %% API
--export([start_link/3,
+-export([start_link/4,
          shutdown/0,
          package_versions/1,
-         package_dependencies/2
+         package_dependencies/2,
+        find_package_location/4,
+        gather_version_info/2
        ]).
 
 %% gen_server callbacks
@@ -48,7 +49,9 @@
 
 -define(SERVER, ?MODULE).
 
--record(state, {urls, 
+-record(state, {prefix,
+               erts_version,
+               erts_versions,
                 version_list = [],
                 dep_list = []}).
 
@@ -57,17 +60,17 @@
 %%====================================================================
 %%--------------------------------------------------------------------
 %% @spec start_link(Urls, InitialDeps, InitialVsns) -> {ok,Pid} | ignore | 
{error,Error}
-%% 
-%% @doc 
+%%
+%% @doc
 %% Starts the server
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
-start_link(Urls, InitialDeps, InitialVsns) ->
-    gen_server:start_link({local, ?SERVER}, ?MODULE, 
-                          [Urls, InitialDeps, InitialVsns], []).
+start_link(Prefix, ErtsVersion, InitialDeps, InitialVsns) ->
+    gen_server:start_link({local, ?SERVER}, ?MODULE,
+                          [Prefix, ErtsVersion, InitialDeps, InitialVsns], []).
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Shut down the process.
 %% @spec shutdown() -> ok
 %% @end
@@ -76,9 +79,9 @@ shutdown() ->
     gen_server:cast(?SERVER, shutdown).
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of versions available for the specified package.
-%% 
+%%
 %% @spec package_versions(Package) -> VersionList | Error
 %% @end
 %%--------------------------------------------------------------------
@@ -86,15 +89,15 @@ package_versions(Package) ->
     gen_server:call(?SERVER, {package_versions, Package}, infinity).
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of dependencies for the specified package and the
 %%  specified version.
-%% 
+%%
 %% @spec package_dependencies(Package, Version) -> Deps | Error
 %% @end
 %%--------------------------------------------------------------------
 package_dependencies(Package, Version) ->
-    gen_server:call(?SERVER, {package_dependencies, Package, Version}, 
+    gen_server:call(?SERVER, {package_dependencies, Package, Version},
                     infinity).
 
 %%====================================================================
@@ -106,14 +109,18 @@ package_dependencies(Package, Version) ->
 %%                     {ok, State, Timeout} |
 %%                     ignore               |
 %%                     {stop, Reason}
-%% 
-%% @doc 
+%%
+%% @doc
 %% Initiates the server
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
-init([Urls, InitialDeps, InitialVsns]) ->
-    ibrowse:start(),
-    {ok, #state{urls=Urls, dep_list=InitialDeps, version_list=InitialVsns}}.
+init([Prefix, ErtsVersion, InitialDeps, InitialVsns]) ->
+    VersionInfo = gather_version_info(Prefix, ErtsVersion),
+    {ok, #state{prefix=Prefix,
+               erts_version=ErtsVersion,
+               erts_versions=VersionInfo,
+               dep_list=InitialDeps,
+               version_list=InitialVsns}}.
 
 %%--------------------------------------------------------------------
 %% @spec handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -122,16 +129,16 @@ init([Urls, InitialDeps, InitialVsns]) ->
 %%                                      {noreply, State, Timeout} |
 %%                                      {stop, Reason, Reply, State} |
 %%                                      {stop, Reason, State}
-%% 
-%% @doc 
+%%
+%% @doc
 %% Handling call messages
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
 handle_call({package_versions, Package}, _From, State) ->
-    try package_versions(State, Package) of     
+    try package_versions(State, Package) of
         {Versions, NState} ->
             {reply, Versions, NState}
-    catch 
+    catch
         throw:_ ->
             {reply, [], State}
     end;
@@ -139,7 +146,7 @@ handle_call({package_dependencies, Package, Version}, 
_From, State) ->
     try package_dependencies(State, Package, Version) of
         {Deps, NState} ->
             {reply, Deps, NState}
-    catch 
+    catch
         throw:_ ->
             {reply, [], State}
     end.
@@ -148,10 +155,10 @@ handle_call({package_dependencies, Package, Version}, 
_From, State) ->
 %% @spec handle_cast(Msg, State) -> {noreply, State} |
 %%                                      {noreply, State, Timeout} |
 %%                                      {stop, Reason, State}
-%% 
-%% @doc 
+%%
+%% @doc
 %% Handling cast messages
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
 handle_cast(shutdown, State) ->
     {stop, normal, State}.
@@ -160,33 +167,33 @@ handle_cast(shutdown, State) ->
 %% @spec handle_info(Info, State) -> {noreply, State} |
 %%                                       {noreply, State, Timeout} |
 %%                                       {stop, Reason, State}
-%% 
-%% @doc 
+%%
+%% @doc
 %% Handling all non call/cast messages
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
 handle_info(_Info, State) ->
     {noreply, State}.
 
 %%--------------------------------------------------------------------
 %% @spec terminate(Reason, State) -> void()
-%% 
-%% @doc 
+%%
+%% @doc
 %% This function is called by a gen_server when it is about to
 %% terminate. It should be the opposite of Module:init/1 and do any necessary
 %% cleaning up. When it returns, the gen_server terminates with Reason.
 %% The return value is ignored.
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
 terminate(_Reason, _State) ->
     ok.
 
 %%--------------------------------------------------------------------
 %% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% 
-%% @doc 
+%%
+%% @doc
 %% Convert process state when code is changed
-%% @end 
+%% @end
 %%--------------------------------------------------------------------
 code_change(_OldVsn, State, _Extra) ->
     {ok, State}.
@@ -194,12 +201,158 @@ code_change(_OldVsn, State, _Extra) ->
 %%====================================================================
 %%% Internal functions
 %%====================================================================
+%%--------------------------------------------------------------------
+%% @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,
+                                ewl_file: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, 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, 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 the dependencies for a package and version.
+%%
+%% @spec (Package, Version, Prefix, Versions) -> Location
+%% @end
+%%--------------------------------------------------------------------
+find_package_location(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 ->
+           get_package_dependencies(Package, Version, Prefix, ErtsVersions)
+    end;
+find_package_location(_, _, _, []) ->
+    throw({error, "Unable to find location for package"}).
+
+
+
+%%--------------------------------------------------------------------
+%% @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,
+                              ewl_file: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,  ErtsVersions) ->
+    AppName = lists:flatten([Package, ".app"]),
+    FileName = get_package_dependencies(Package, Version,
+                                       Prefix, ErtsVersions),
+    case file:consult(filename:join(FileName, "ebin", AppName)) of
+       {ok, [Term]} ->
+           handle_parse_output(Term);
+       {error, _} ->
+           throw({error, "Unable to find dependencies for package"})
+    end.
 
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of versions available for the specified package.
-%% 
+%%
 %% @spec package_versions(Urls, Package) -> VersionList | Error
 %% @end
 %%--------------------------------------------------------------------
@@ -209,9 +362,11 @@ package_versions(State, Package) when is_atom(Package) ->
         {value, {Package, Versions}} ->
             {Versions, State};
         false ->
-            Suffix = ewr_util:gen_metadata_stub_suffix(Package),
-            Versions = try_get_package_versions(State#state.urls, Suffix),
-            {Versions, State#state{version_list=[{Package, Versions} | VList]}}
+            Versions = get_package_versions(Package,
+                                           State#state.prefix,
+                                           State#state.erts_versions,
+                                           []),
+           {Versions, State#state{version_list=[{Package, Versions} | VList]}}
     end;
 package_versions(_, _) ->
     throw({error, "Package name must be an atom"}).
@@ -219,10 +374,10 @@ package_versions(_, _) ->
 
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of dependencies for the specified package and the
 %%  specified version.
-%% 
+%%
 %% @spec package_dependencies(Urls, Package, Version) -> Deps | Error
 %% @end
 %%--------------------------------------------------------------------
@@ -234,109 +389,16 @@ package_dependencies(State, Package, Version) ->
             {Value, State};
         false ->
             NPackage = atom_to_list(Package),
-            NVersion = ewr_util:version_to_string(Version),
-            Suffix = ewr_util:gen_metadata_suffix(NPackage, NVersion),
-            NDeps = try_get_package_dependencies(State#state.urls, 
-                                                 NPackage, Suffix),    
+            NDeps = get_package_dependencies(NPackage,
+                                            Version,
+                                            State#state.prefix,
+                                            State#state.erts_versions),
             {NDeps, State#state{dep_list=[{Key, NDeps} | Deps]}}
     end.
 
 
 %%--------------------------------------------------------------------
-%% @doc 
-%%  Try to get the list of package dependencies
-%%
-%% @spec try_get_package_dependencies(Urls, Package, Suffix) -> DepList | 
{error, Reason}
-%% @end
-%%--------------------------------------------------------------------
-try_get_package_dependencies([Url | T], Package, Suffix) ->
-    NUrl = lists:flatten([Url, Suffix, Package, ".app"]),
-    case ewr_util:consult_url(NUrl) of
-       {ok, Term} ->
-           handle_parse_output(Term);
-       {error, _} ->
-           try_get_package_dependencies(T, Package, Suffix)
-   end;
-try_get_package_dependencies(_, Package, _) ->
-    error_logger:warning_msg("Package ~w is not in repository! unable to "
-                             "resolve dependencies.~n",
-                             [Package]),
-    throw({error, "Unable to find package dependecies"}).
-
-%%--------------------------------------------------------------------
-%% @doc 
-%%  Try to get the list of package versions from the system.
-%%
-%% @spec try_get_package_versions(Urls, Suffix) -> Term | {error, Reason}
-%% @end
-%%--------------------------------------------------------------------
-try_get_package_versions([Url | T], Suffix) ->
-    NUrl = lists:flatten([Url, Suffix]),
-    case ibrowse:send_req(NUrl, [{"Connection", "TE"}, 
-                                {"TE", "trailers"}, 
-                                {"Depth", "1"}, 
-                                {"Content-Type", "application/xml"}], 
-                          propfind, "") of
-        {ok, "207", _, Body} -> 
-            parse_out_package_version(Body);
-        {ok, _, _, _} -> 
-            try_get_package_versions(T, Suffix);
-        {error, _} ->
-            try_get_package_versions(T, Suffix)
-    end;
-try_get_package_versions([], Suffix) ->
-    error_logger:warning_msg("Unable to find version list at ~s. Package 
probably "
-                             "isn't in any of the available repositories~n", 
[Suffix]),
-    throw({error, "Unable to find version list"}).
-
-
-%%--------------------------------------------------------------------
-%% @doc 
-%%  Parse out the package version list from the returned string.
-%% @spec parse_out_package_version(Body) -> VersionList
-%% @end
-%%--------------------------------------------------------------------
-parse_out_package_version(Body) ->
-    case xmerl_scan:string(Body, []) of
-        {Elem, _} ->
-            get_package_versions(Elem);
-        Err ->
-            throw(Err)
-    end.
-
-%%--------------------------------------------------------------------
-%% @doc 
-%%  Get the list of items from the parsed xml.
-%% @spec get_package_versions(Elem) -> Vn
-%% @end
-%%--------------------------------------------------------------------
-get_package_versions(Elem) ->
-    case lists:sort(xmerl_xs:value_of(xmerl_xs:select("//D:href", Elem))) of
-        [H | T] ->
-            gather_versions(H, T);
-        [] ->
-            [];
-        Else ->
-            throw({error, {got_from_url, Else}})
-    end.
-
-%%--------------------------------------------------------------------
-%% @doc 
-%%  Parse out the version from the full url.
-%% @spec gather_versions(Base, Rest) -> VersionList
-%% @end
-%%--------------------------------------------------------------------
-gather_versions(Base, Rest) ->
-    gather_versions(length(Base), Rest, []).
-
-gather_versions(Base, [H | T], Acc) ->
-    gather_versions(Base, T,
-       [ewr_util:parse_version(string:strip(lists:nthtail(Base, H), both, $/)) 
| Acc]);
-gather_versions(_Base, [], Acc) ->
-    Acc.
-
-%%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  get the version the deps and the versioned deps from an *.app
 %%  term.
 %%
@@ -353,7 +415,7 @@ handle_parse_output(_) ->
 
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of versioned dependencies from the op list.
 %% @spec get_vdeps(OppList) -> VersionedDependencies
 %% @end
@@ -367,7 +429,7 @@ get_vdeps([]) ->
     undefined.
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Process the list of versioned dependencies.
 %% @spec process_vdeps(VList, Acc) -> VersionedList
 %% @end
@@ -381,7 +443,7 @@ process_vdeps([], Acc) ->
     Acc.
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of non-versioned dependencies from the oplist. This
 %%  is specifed in the applications entry.
 %% @spec get_deps(OpList) -> Dependencies
@@ -397,7 +459,7 @@ get_deps([]) ->
 
 
 %%--------------------------------------------------------------------
-%% @doc 
+%% @doc
 %%  Get the list of included applications.
 %% @spec get_ideps(OpList) -> IncludedDependencies
 %% @end
@@ -410,8 +472,6 @@ get_ideps([_ | T]) ->
 get_ideps([]) ->
     [].
 
-
-
 %%====================================================================
 %% tests
 %%====================================================================
@@ -423,8 +483,30 @@ handle_parse_output_test() ->
               [{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}, 
+    ?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.4


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