[Rubygems-developers] Design notes for RubyGems 2
gsinclair at soyabean.com.au
Tue Jun 8 19:15:26 EDT 2004
On Wednesday, June 9, 2004, 4:15:52 AM, Curt wrote:
> Chad Fowler wrote:
>> On Wed, 9 Jun 2004, Gavin Sinclair wrote:
>> # The reality is that RubyGems is pretty simple. I want an interface to
>> # the main thing in the system - the collection of gems - that is also
>> # simple. Tell it want you want and you get it. Obviously that needs
>> # to be codified somewhat. But the current system is more like
>> # low-level scratching than high-level ease.
>> Agreed on the simplicity comment. To me, the interface you're talking
>> about looks something like this:
>> Gem::Cache.from_installed_gems.each do |gemspec|
>> There might be some things lacking, but I'd like to see them built based
>> on a concrete need for them.
> Why not:
> repo = new Repository(LOCALHOST)
> repo.each_installed_gem do |gem|
> (Of course, the first two lines could be written as one line.)
I'll go you halfway. Generating RDoc is a process, so I'd use
Tools::RDocGenerator to implement that process. Now you don't
actually need a Gem for that; you need a directory (that's where turn
'rdoc' loose) and the gemspec (giving you RDoc options, etc.).
# We don't create Repositories often; they are long-living objects
# that know about all local and remote gems. So we just use the
# 'repo' object that's available to us.
installed_gems = repo.gem_report(:installed)
# -> [ GemResource<rake, 0.3.2, :installed, /usr/lib/ruby/gems/1.8>,
GemResource<pqa, 0.6, :installed, /usr/lib/ruby/gems/1.8>,
installed_gems.each do |gem_resource|
In Chad's example, "Gem::DocManager.new(gemspec).generate_rdoc" has no
way of knowing *where* the gem is installed. Not even Cache can tell
In Curt's example, a Gem object (if that's what 'gem' is) knows how to
generate RDoc, which is an inappropriate abstraction, I believe.
> A GUI gems browser is going to want to have a navigation tree control that
> can enumerate known repositories (local and remote) and the gems within each
> repository. Once enumerated and displayed, if the user selects an item in
> the GUI tree, it needs to know what that corresponds to.
In my design, as demonstrated above, the Repository gives you
GemResource objects. Given a random GemResource object 'gr', you can:
gr.name -> rake
gr.version -> 0.3.2
gr.installed? -> false
gr.cellared? -> false
gr.remote? -> true
gr.location_category -> :remote
gr.source -> 'http://raa.ruby-lang.org/gems'
You want to retrieve this gem?
gem = repo.get_gem(gr)
gem.name -> rake
gem.version -> 0.3.2
gem.fullname -> rake-0.3.2
gem.spec -> Gem::Specification<...>
gem.data -> "..." (raw data)
gem.extract("README") -> "..."
gem.extract_all do |path, data|
# Hey, installation is pretty easy with this!
Now we can cellar it:
# Rough implementation:
# cellar_dir = Directories.cellar(base_dir)
# cellar_path = File.join(cellar_dir, gem.fullname + '.gem')
# File.write(cellar_path, gem.data)
Or install it:
Tools::Installer.install(gem, base_dir, repo)
# Rough implementation
# # Deal with dependencies.
# gem.spec.dependencies.each do |name, version_req|
# unless repo.installed?(name, version_req)
# # Communicate with app somehow to confirm installation.
# dep_gem = repo.get_gem(name, version_req)
# Installer.install(dep_gem, base_dir, repo)
# # Now deal with the gem at hand.
# install_dir = Directories.installation(base_dir, gem)
# Dir.chdir(install_dir) do
# gem.extract_all do |path, data|
# File.write(path, data)
Or if we have an _installed_ GemResource and we want to uninstall it:
gr.installed? -> true
gr.source -> '/usr/lib/uby/gems/1.8'
# Rough implementation.
# return unless gr.installed?
# base_dir = gr.source
# install_dir = Directories.installation(base_dir)
I hope that gives I decent idea of the API I had in mind. All of that
is off the top of my head, so there could be inconsistencies or room
for improvement in there.
More information about the Rubygems-developers