Finding Libraries by Querying Gem Respositories

Problem

You want to find new gems to install on your system, or see which gems you already have installed.

Solution

From the command line, use gems query command:

	$ gem query
	*** LOCAL GEMS ***

	sources (0.0.1)
	 This package provides download sources for remote gem installation

	$ gem query --remote
	*** REMOTE GEMS ***
	actionmailer (1.1.1, 1.0.1, 1.0.0, 0.9.1, 0.9.0, 0.8.1, …)
	 Service layer for easy email delivery and testing.

	actionpack (1.10.1, 1.9.1, 1.9.0, 1.8.1, 1.8.0, 1.7.0, …)
	 Web-flow and rendering framework putting the VC in MVC.

	[… Much more output omitted ….]

From Ruby code, use Gem::cache to query your locally installed gems, and Gem::RemoteInstaller#search to query the gems on some other site. Gem::cache can be treated as an Enumerable full of tasty Gem::Specification objects. Gem::Remote-Installer#search returns an Array containing an Array of Gem::Specification objects for every remote source it searched. Usually there will only be one remote sourcethe main gem repository on rubyforge.org.

This Ruby code iterates over the locally installed gems:

	require 
ubygems

	Gem::cache.each do |name, gem|
	 puts %{"#{gem.name}" gem version #{gem.version} is installed.}
	end
	# "sources" gem version 0.0.1 is installed

The format_gems method defined below gives a convenient way of looking at a large set of Gem::Specification objects. It groups the gems by name and version, then prints a formatted list:

	require 
ubygems/remote_installer
	require yaml

	def 
format_gems(gems)
	 gem_versions = gems.inject({}) { |h, gem| (h[gem.name] ||= []) << gem; h}
	 gem_versions.keys.sort.each do |name|
	 versions = gem_versions[name].collect { |gem| gem.version.to_s }
	 puts "#{name} is available in these versions: #{versions.join(, )}"
	 end
	end 

Here it is being run on the gems available from RubyForge:

	format_gems(Gem::RemoteInstaller.new.search(/.*/).flatten)
	# Asami is available in these versions: 0.04
	# Bangkok is available in these versions: 0.1.0
	# Bloglines4R is available in these versions: 0.1.0
	# BlueCloth is available in these versions: 0.0.2, 0.0.3, 0.0.4, 1.0.0
	# …

Discussion

Not only are Ruby gems a convenient packaging mechanism, they e an excellent way to find out about new pieces of Ruby code. The gem repository at rubyforge.org is the canonical location for Ruby libraries, so youve got one place to find new code.

You can query the gems library for gems whose names match a certain regular expression:

	$ gem query --remote --name-matches "test"
	** REMOTE GEMS ***

	lazytest (0.1.0)
	 Testing and benchmarking for lazy people

	test-unit-mock (0.30)
	 Test::Unit::Mock is a class for conveniently building mock objects
	 in Test::Unit test cases.

	testunitxml (0.1.4, 0.1.3)
	 Unit test suite for XML documents
	ZenTest (3.1.0, 3.0.0)
	 == FEATURES/PROBLEMS

Or, from Ruby code:

	format_ 
gems(Gem::RemoteInstaller.new.search(/test/i).flatten)
	# ZenTest is available in these versions: 3.0.0, 3.1.0
	# lazytest is available in these versions: 0.1.0
	# test-unit-mock is available in these versions: 0.30
	# testunitxml is available in these versions: 0.1.3, 0.1.4

This method finds gems that are newer than a certain date. It has to keep around both a Date and a Time object for comparisons, because RubyForge stores some gems dates as Date objects, some as Time objects, and some as string representations of dates.[1]

[1] This is because of differences in the underlying gem specification files. Different people build their gemspecs in different ways.

	require date

	def gems_newer_than(date, 
query=/.*/)
	 time = Time.local(date.year, date.month, date.day, 0, 0, 0)
	 gems = Gem::RemoteInstaller.new.search(query).flatten
	 gems.reject do |gem|
	 gem_date = gem.date
	 gem_date = DateTime.parse(gem_date) if gem_date.respond_to? :to_str
	 gem_date < (gem_date.is_a?(Date) ? date : time)
	 end
	end

	todays_gems = gems_newer_than(Date.today-1)
	todays_gems.size #=> 7
	format_gems(todays_gems)
	# filament is available in these versions: 0.3.0
	# mechanize is available in these versions: 0.4.1
	# mongrel is available in these versions: 0.3.12.1, 0.3.12.1
	# rake is available in these versions: 0.7.1
	# rspec is available in these versions: 0.5.0
	# tzinfo is available in these versions: 0.2.0

By default, remote queries look only at the main gem repository on rubyforge.org:

	Gem::RemoteInstaller.new.sources # => ["http://gems.rubyforge.org"]

To query a gem repository other than rubyforge.org, pass in the URL to the repository as the --source argument from the command line. This code starts a gem server on the local machine (it can serve all of your installed gems to other machines), and queries it:

	$ gem_server &

	$ gem query --remote --source http://localhost:8808
	# *** REMOTE GEMS ***
	# Updating Gem source index for: http://localhost:8808
	# sources (0.0.1)
	# This package provides download sources for remote gem 
installation

From Ruby code, modify the Gem.sources variable to retrieve gems from another source:

	Gem.sources.replace([http://localhost:8808])
	format_ 
gems(Gem::RemoteInstaller.new.search(/.*/).flatten)
	# sources is available in these versions: 0.0.1

See Also

  • Recipe 18.7, "Distributing Your Gems," for more on hosting your own gem repository
  • The Ruby Application Archive is a companion to rubyforge.org: rather than hosting Ruby projects, it links to Ruby packages hosted all around the Web; you e more likely to see projects on the RAA that aren packaged as gems (see Recipe 18.8 for tips on installing them)


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net