Joe,<div><br></div><div>The real question is what a "package manager" is supposed to do. What are the problems that it should solve?</div><div><br></div><div>My current take is:</div><div><br></div><div>1. Library (package) discovery (search)</div><div>2. Library location/retrieval</div><div>3. Dependencies</div><div>4. Library publishing (enabling 1)</div><div><br></div><div>After my experience with Agner (http://erlagner.org) I've moved onto a much more lightweight approach I am using in EXPM (http://expm.co) [http://rashkovskii.com/2012/10/01/expm-or-meet-agner-2/]. </div><div><br></div><div>It is essentially an index and, technically speaking, EXPM does not know how to retrieve or build libraries in that index. It does know, however, how to instruct rebar, mix or an scm of choice (git only at the moment) to get the library. If you look at some package, for example http://expm.co/cowboy/head, at the bottom you'll see those automatically generated "instructions". The command line tool is capable of exactly that as well.</div><div><br></div><div>I believe that EXPM currently addresses 1 & 2 to a reasonable extent and it has an incomplete support for 3 (dependencies). Not by design, just because it is young. It can figure out the exact versions of dependencies given constraints, but it doesn't do dependencies' dependencies (yet). This can be easily circumvented by writing a simple shell script that'll run expm deps over expm deps output (recursion!)</div><div><br></div><div>EXPM also does a fairly good job at 4 — you can easily publish a package with no need to go through a registration procedure (yet your package updates are protected). It isn't without minor flaws, but it works pretty well so far.</div><div><br></div><div>I personally think that either rebar or mix are good tools for retrieving dependencies and EXPM or another similar tool to assist with finding what libraries to use and where are they located is a good way to go.</div><div><br></div><div>Just my 2c</div><div><br>On Friday, October 19, 2012 3:36:34 AM UTC-7, Joe Armstrong wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Here is a programming exercise ...
<br>
<br>I think we can turn rebar into a package manager with 4 simple and one not so
<br>simple tweaks.
<br>
<br>This would turn rebar from being something that is very useful to something
<br>that is very very useful :-)
<br>
<br>
<br>(aside - I'm revising my Erlang book, and I'd like to describe
<br>how package management works, but there is no package manager
<br>which is a shame - so I got to thinking about package managers
<br>and wondered why still don't have a decent package manager.        
<br>
<br>The one I've seen that I like a lot is npm (node package manager)
<br>so we could do worse than follow their design)
<br>
<br>So this is how I think rebar could become a package manager
<br>
<br>
<br>Tweak 1
<br>=======
<br>
<br>   > rebar get-deps
<br>
<br>Fetches the dependencies in rebar.conf and stores them in
<br>the current directory, in a directory called deps.
<br>
<br>After a while you get dependencies scattered all over the place,
<br>I've seen many examples of this.
<br>
<br>This means that there is no central place to go and look if you
<br>want to find code.
<br>
<br>NPM sticks ALL dependencies under ${HOME}/.npm
<br>
<br>Suggestion:
<br>
<br>   All dependencies should be stored in ${HOME}/.erl_packages
<br>
<br>   (Aside - if we followed npm the directory structure would be
<br>    something like)
<br>
<br>   ${HOME}/.erl_packages/cowboy/<wbr>6.2.1/src
<br>                                                               /ebin
<br>                                                     /5.2.3
<br>                        /stdlib/12.3.1
<br>                               /14.6.8
<br>
<br>   etc. ie a package/Vsn/src ... structure
<br>
<br>
<br>Tweak 2
<br>=======
<br>
<br>   move rebar.config to ${HOME}/.erl_packages/rebar.<wbr>config
<br>   and add commands to automatically edit it
<br>
<br>   > rebar add_package foo
<br>
<br>   might add a line like
<br>   {foo, ".*", "git://...."}
<br>
<br>   to rebar.config
<br>
<br>   The point here is to change the content of rebar.config with
<br>   shell commands rather that editing it by hand
<br>
<br>Tweak 3
<br>=======
<br>   fix rebar so it just downloads a particular version of a
<br>   program and not all the .git stuff - most people will only
<br>   want to use other peoples code, not hack it.
<br>
<br>Tweak 4
<br>=======
<br>
<br>Fix the erlang load paths to find all the dependencies
<br>
<br>I do this now. Put all my dependencies in
<br>${HOME}/nobackup/erlang_<wbr>imports/deps and put the following
<br>code in my .erlang startup file
<br>
<br>  Home = os:getenv("HOME").
<br>  Dir = Home ++ "/nobackup/erlang_imports/<wbr>deps",
<br>  case file:list_dir(Dir) of
<br>     {ok, L} ->
<br>         lists:foreach(fun(I) ->
<br>                               Path = Dir ++ "/" ++ I ++ "/ebin",
<br>                               code:add_path(Path)
<br>                       end, L);
<br>    _ ->
<br>        void
<br>  end.
<br>
<br>Tweak 5
<br>=======
<br>   This can't be done by rebar
<br>   Make an index of all erlang apps on github that follow
<br>   the erlang packaging structure
<br>
<br>   Somebody has to write a program to do this.
<br>
<br>   The package index should be at a well know URL
<br>
<br>   > rebar get_index
<br>
<br>
<br>   This should fetch the  index from the well-know URL and store in
<br>   ${HOME}/.erl_packages
<br>
<br>
<br>   > rebar search XXX
<br>
<br>   would search the fetched index        
<br>
<br>   > rebar add XXXX
<br>
<br>   would take the index entry add it to the config fill fetch the code
<br>   and compile it
<br>
<br>Note the following:
<br>
<br>1) The trust model.
<br>
<br>   We trust the supplier of a program not the program.
<br>
<br>   So for example on github we might trust programs
<br>   published by the user joearms (me) or erlang (the OTP release)
<br>   but not by some_guy_ive_never_hear_of
<br>
<br>   It would be quite easy to add a trust section to rebar.config
<br>
<br>   {trust, ["git://joearms", git://erlang", ...]}
<br>
<br>2) There is no "publish" step
<br>
<br>   We put our code on github (or somewhere) and hope that it gets indexed
<br>   by the indexer.
<br>
<br>   We might mail the indexer if it is published in an obscure place.
<br>
<br>  Comments?
<br>
<br>   Cheers
<br>
<br>/Joe
<br>______________________________<wbr>_________________
<br>erlang-questions mailing list
<br><a href="javascript:" target="_blank" gdf-obfuscated-mailto="NafHShmXmVkJ">erlang-q...@erlang.org</a>
<br><a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-questions</a>
<br></blockquote></div>