Skip to content

Instantly share code, notes, and snippets.

@kch
Created September 23, 2010 14:15
Show Gist options
  • Save kch/593671 to your computer and use it in GitHub Desktop.
Save kch/593671 to your computer and use it in GitHub Desktop.
Convert a Heroku .gems file to a Bundler Gemfile
#!/usr/bin/env ruby
# encoding: UTF-8
require 'strscan'
(puts DATA.read.gsub(/\$0/, File.basename($0)); exit 1) unless ARGV.empty? # handled -h and anything else since we don't take args
# tokenize lines
lines = STDIN.read.strip.split(/\n+/)
gems = lines.inject({}) do |h, line|
next h if line =~ /^\s*(#.*)?$/
ss = StringScanner.new(line.strip)
name = ss.scan(/\S+/) or raise "Don't know what to do with: #{line}"
h[name] = {}
until ss.eos?
ss.skip(/\s+/)
if ss.scan(/-\w|--\w\w+/) and key = ss[0]
ss.skip(/\s*(=\s*)?/)
ss.scan(/'(.*?)(?!<\\)'/) or
ss.scan(/"(.*?)(?!<\\)"/) or
ss.scan(/(\S+)/) or raise "Expected value for key #{key} in #{ss.rest}"
h[name][key] = ss[1]
else ss.skip(/#.*/) or raise "Unexpected: #{ss.rest}"
end
end
h
end
# semantic validation
gems.each do |name, options|
s = options.delete("-s") || options.delete("--source") and options[:source] = s
v = options.delete("-v") || options.delete("--version") and options[:version] = v
invalid_keys = options.keys - [:source, :version]
invalid_keys.empty? or raise "Invalid keys for gem '#{name}': #{invalid_keys.join(",")}"
end
# output Gemfile
puts "source :rubygems"
gems.values.each do |options|
next unless source = options.delete(:source)
puts "source #{source.inspect}"
end
puts
gems.each do |name, options|
name_version = [name, options.delete(:version)].compact
puts "gem #{name_version.map(&:inspect).join(', ')}"
end
__END__
Convert Heroku gem manifest format (.gems) to Bundler format (Gemfile)
Usage:
$0 < .gems
$0 < .gems > Gemfile
@kch
Copy link
Author

kch commented Sep 23, 2010

Now also as a real github project: http://github.com/kch/gemfile-from-dotgems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment