Gem Platform Matching
Eric Hodel | Sat, 25 Aug 2007 20:59:31 GMT
RubyGems now figures out if your platform matches the gem you want to install, and here’s how it does it.
First, the platform is compared to the list of legacy platforms. These are the platform strings that currently exist in the gems.rubyforge.org index. If the platform matches one of these it is expanded into an Array of CPU, OS and OS version. (New platforms are already an Array.)
Next the platform is compared with your RubyGems configured platforms (“ruby” and your OS platform by default) to see if any match. A platform’s CPU will match if it matches the local platform’s CPU exactly or if either side is ‘universal’. The OS must match exactly. Either OS version can be nil, or it must match exactly.
A potential improvement to the platform matching would be to upgrade a platform to a real object from an Array and make the OS version a Gem::Version and encode in each OS’ versioning scheme. I don’t think there is much benefit to that at present since most gems with platforms are for win32 which doesn’t have versions in Config::CONFIG[‘arch’].
Dear Lazyweb: Gem Platforms
Eric Hodel | Tue, 21 Aug 2007 02:53:04 GMT
As you may or may not have heard, RubyGems will be merged into Ruby 1.9 sometime in October. Before this can happen RubyGems needs to automatically install dependencies based on platforms. Fortunately I’ve got the automatic install part written. Unfortunately I don’t know if I’ve got figuring out the platforms right. This is where you come in.
Dear Lazyweb,
Here’s my proposal for how we recognize platforms. From Config::CONFIG, take the arch, split it on ’-’ into cpu and os and run os through a case statement to figure out OS and OS version (if any). Combine the cpu, OS and OS version. This value is your platform.
(There will be a rubygems-platforms.gem much like sources.gem that can be updated as necessary.)
Using the tattle data, the following code recognizes 29 unique platforms:
def match(arch)
cpu, os = arch.split '-', 2
cpu, os = nil, cpu if os.nil? # java
cpu = case cpu
when /i\d86/ then 'x86'
else cpu
end
os = case os
when /cygwin/ then [ 'cygwin', nil ]
when /darwin(\d+)?/ then [ 'darwin', $1 ]
when /freebsd(\d+)/ then [ 'freebsd', $1 ]
when /^java$/ then [ 'java', nil ]
when /^java([\d.]*)/ then [ 'java', $1 ]
when /linux/ then [ 'linux', $1 ]
when /mingw32/ then [ 'mingw32', nil ]
when /mswin32/ then [ 'mswin32', nil ]
when /openbsd(\d+\.\d+)/ then [ 'openbsd', $1 ]
when /solaris(\d+\.\d+)/ then [ 'solaris', $1 ]
else [ 'unknown', nil ]
end
[cpu, os].flatten.compact.join("-")
end
require 'rbconfig'
arch = Config::CONFIG['arch']
cpu, os = arch.split '-', 2
puts "Your cpu is: #{cpu.inspect}"
puts "Your os is: #{os.inspect}"
puts "Your platform is: #{match(arch).inspect}"
raise "need a tattle arch dump yaml file!" if ARGV.empty?
puts "loading archs..."
require 'yaml'
archs = YAML.load(ARGF.read)['arch'].keys
def recognize(*archs)
unmatched = {}
seen = {}
archs.each do |arch|
platform = match arch
seen[platform] = true
unmatched[arch] = true if platform =~ /-unknown$/
end
return unmatched.keys, seen.keys
end
unmatched, unique = recognize(*archs)
puts "found #{unique.length} unique platforms"
puts
puts unique.sort.join("\n")
unless unmatched.empty? then
puts
puts "unmatched"
puts
puts unmatched.join("\n")
end
Lazyweb, I have two major questions for you:
Did I get something wrong? Am I using autoconf’s target_os correctly? Is Solaris 2.8 really incompatible with Solaris 2.9? What is a 64-bit Windows’ target_os value?
Do I have all the platforms people run Ruby and RubyGems on? If the answer to this one is no, do this: gem install tattle; tattle. (Yes, AIX users, I’m talking to you.)
UPDATE: I switched from target_os and target_cpu to arch to support modern JRuby, thanks Nick Sieger! See ruby-talk:265596.
Finding Random Reading
Eric Hodel | Mon, 20 Aug 2007 03:13:43 GMT
I’m really missing what reddit used to give me, which was things I liked to read that I didn’t know I wanted to read on the front page. Now reddit is full of dups and political stuff I don’t care about. It also has a recomendation feature never worked for me, I couldn’t tell the difference between it and the home page.
Google News solves the dup problem but has too much stuff I don’t care about. Sometimes it makes me laugh, but it still doesn’t tell me what to read, or even what I probably will like.
The recommendation service I love is Netflix’s, I’ve rated over 350 movies now and it is spookily good at picking movies I like. For example 11:14 has a silly-sounding plot summary:
Five seemingly random story lines intersect at precisely 11:14 p.m. in this innovative drama-thriller written and directed by newbie filmmaker Greg Marcks. Even though they’re strangers, Buzzy, Mark, Cheri, Jac and Eddie will become a part of one another’s lives—even if it kills them.
I forgot why I added it to my queue. When it arrived I thought it would be silly, but I really enjoyed it, and that wasn’t the first movie I’ve experienced this with. Also, it tells me to watch things like Afro Samurai and Tinker, Tailor, Soldier, Spy that I would never hear about or know about otherwise.
What I really want is Netflix for for my random web reading. I don’t care about what’s popular, I care about what is well-written and interesting. Does this kind of thing exist yet?
Until then, I think I’m going to switch to clicking wikipedia’s Random article button when I get bored.
Two Weeks of Vacation, Vlad, RubyGems
Eric Hodel | Fri, 17 Aug 2007 21:04:05 GMT
I’m not working this month so I can do whatever I want. So far that’s featured:
- The long overdue MogileFS 1.2.1 with a minor bugfix
- A mostly-evil
Kernel#callerenhancement, SuperCaller 1.0.0 - memcache-client 1.5.0 with a couple of new features
- Sphincter 1.1.0 with friendlier setup and association inclusion
- The first release of Vlad the Deployer by the Ruby Hit Squad
- Tons of hacking on RubyGems
Building Vlad was a lot of fun. Ryan and I flew up Wilson Bilkovich, watched Bourne Ultimatum, then hacked for four days straight to bring Vlad into the world.
InfoQ published an interview with us about Vlad:
Capistrano, a popular deployment tool for Rails, is challenged by Vlad the Deployer, a tool which offers similar functionality with a much simpler implementation. We talked to the Ruby Hit Squad group that released version 1.0 of Vlad.
—Capistrano gets competition: Vlad the Deployer via InfoQ
The RubyGems hacking has been mostly bug fixes and refactoring so far. I’m working towards teaching RubyGems your platform so it can automatically install the correct version.
Here’s a sample of what’s I’ve done to RubyGems so far:
- —sources is no longer remembered forever, use `gem sources` to manage the permanent list
- The sources gem is gone, RubyGems uses a built-in list now (but can be upgraded in the future)
- `gem list` respects its default of just gem names now
- Only exact gem names are matched on install, “foo_bar 2.0” won’t install instead of “foo 1.0” if you run `gem install foo`
- RubyGems requires only what it needs when you
require 'rubygems' - Fewer bulk updates when updating the gem index
- `gem dep -r` lists dependencies for remote gems
- `gem info -r` shows information for remote gems
- `gem -v` turns on “really verbose” mode (verbose mode is the default)
- `gem_mirror`, `gem_server`, `gemlock`, `gemri`, `gemwhich`, `index_gem_repository.rb` have been merged into `gem`
David Black Explains Bang Methods
Eric Hodel | Wed, 15 Aug 2007 18:23:07 GMT
I’ve seen an explosion of silly bang methods that don’t follow Ruby’s usage, and I’ve been meaning to write exactly this post:
In Ruby, you can write methods whose names end in ! (exclamation point or “bang”). There’s a lot of confusion surrounding the matter of when, and why, you would want to do so.
The ! in method names that end with ! means, “This method is dangerous”—or, more precisely, this method is the “dangerous” version of an otherwise equivalent method, with the same name minus the !. “Danger” is relative; the ! doesn’t mean anything at all unless the method name it’s in corresponds to a similar but bang-less method name.
Sphincter version 1.1.0 has been released!
Eric Hodel | Tue, 14 Aug 2007 03:10:51 GMT
Sphincter uses Dmytro Shteflyuk’s sphinx Ruby API and automatic configuration to make totally rad ActiveRecord searching. Well, you still have to tell Sphincter what models you want to search. It doesn’t read your mind.
When updating to 1.1.0, run: rake sphincter:setup_sphinx
Changes in 1.1.0:
- 2 major enhancements:
- Fields across relationships may be included via add_index.
- Sphincter now automatically configures Dmytro Shteflyuk’s sphinx API. Run `rake sphincter:setup_sphinx` and check in vendor/plugins/sphinx.
- 1 bug fix:
- `rake sphincter:index` task didn’t correctly run reindex. Bug submitted by Lee O’Mara.
memcache-client version 1.5.0 has been released!
Eric Hodel | Tue, 14 Aug 2007 02:50:12 GMT
memcache-client is a client for Danga Interactive’s memcached.
Changes in 1.5.0:
- Add MemCache#flush_all command. Patch #13019 and bug #10503. Patches submitted by Sebastian Delmont and Rick Olson.
- Type-cast data returned by MemCache#stats. Patch #10505 submitted by Sebastian Delmont.
SuperCaller version 1.0.0 has been released!
Eric Hodel | Sun, 05 Aug 2007 04:40:00 GMT
SuperCaller adds a beefed-up version of Kernel#caller and a beefed up version of Exception#backtrace.require 'super_caller'
def something() super_caller end
stack = something
p stack.first.file # => "-"
p stack.first.line # => 4
p stack.first.method_name # => nil
p stack.first.self # => main
p stack.first.sexp # => [:vcall, :super_caller]
p stack.first.source # => "def something\n super_caller\nend"
Changes in 1.0.0 / 2007-06-30:
- 1 major enhancement
- Birthday!
mogilefs-client version 1.2.1 has been released!
Eric Hodel | Thu, 02 Aug 2007 01:40:14 GMT
mogilefs-client version 1.2.1 has been released!
http://seattlerb.org/mogilefs-client
A Ruby MogileFS client. MogileFS is a distributed filesystem written by Danga Interactive. This client supports NFS and HTTP modes.
Changes in 1.2.1:
- Switched to Hoe.
- Moved to p4.
- Fixed bug #7273 in HTTP mode of client where data would not get returned. Submitted by Matthew Willson.
Vacation!
Eric Hodel | Wed, 01 Aug 2007 19:18:10 GMT
Yesterday was my last day working for Lime Spot, so now I’m on vacation for the month of August.
Most of my time is going to be spent working on various bits of software, like adding the automatic platform selection to RubyGems and getting it ready for inclusion in ruby 1.9, cleaning up some RDoc and ruby documentation tickets and going through the rest of my open tracker items on RubyForge.
But today, its time to watch the Simpsons movie, then Taxi Driver!

Articles