This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Rich Meyers
committed
Sep 26, 2011
1 parent
94eda48
commit 7390014
Showing
3 changed files
with
110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#!/usr/bin/env ruby | ||
# The `rpg-parse-gemfile` program reads a Bundler Gemfile and writes a | ||
# list of packages on standard output suitable for feeding to `rpg-install`. | ||
# | ||
# Usage | ||
# ----- | ||
# | ||
# Given a project with a Gemfile, it is possible to install its dependencies | ||
# by running: | ||
# | ||
# rpg install $(rpg parse-gemfile /path/to/Gemfile) | ||
# | ||
# Caveats | ||
# ------- | ||
# | ||
# At this time only top-level gem statements are actually supported. | ||
# All options are ignored. All groups other than the top-level group are | ||
# ignored. All other statements are ignored. | ||
# | ||
# Bundler uses dependency declarations in all groups when resolving | ||
# dependencies, even in groups that are not being installed. | ||
# See http://yehudakatz.com/2010/05/09/the-how-and-why-of-bundler-groups/, | ||
# section "Consistency". This may render a Gemfile unresolvable if, for | ||
# example, the test group specifies conflicting or broken dependencies, even | ||
# for users who don't want to install the test group. rpg ignores all groups | ||
# that are not being installed during dependency resolution. As a consequence, | ||
# rpg and Bundler may install different sets of packages from the same Gemfile. | ||
USAGE = <<BANNER | ||
Usage: rpg-parse-gemfile [PATH] | ||
Convert Bundler Gemfile to a list of packages suitable for installation. | ||
Reads a Gemfile located at specified PATH, or standard input, and writes | ||
a list of packages suitable for feeding to rpg-install on standard output. | ||
Try: rpg install $(rpg parse-gemfile /path/to/Gemfile) | ||
BANNER | ||
|
||
if ARGV.include?('--help') || ARGV.length > 1 || ARGV.empty? && STDIN.tty? | ||
puts USAGE | ||
exit 2 | ||
end | ||
|
||
class GemfileParser | ||
def initialize | ||
@packages = [] | ||
end | ||
|
||
def parse(gemfile_text, file=nil) | ||
eval(gemfile_text, nil, file) | ||
end | ||
|
||
def method_missing(name, *args) | ||
#puts "Ignoring #{name}" | ||
end | ||
|
||
def gem(name, *args) | ||
unless args.first.is_a?(Hash) | ||
version = args.shift | ||
end | ||
options = args.shift || {} | ||
@packages << { | ||
:name => name, :version => version, :options => options, | ||
:group => @in_group, | ||
} | ||
end | ||
|
||
def group(name) | ||
if @in_group | ||
raise ArgumentError, 'Nested groups are not supported' | ||
end | ||
@in_group = name | ||
yield | ||
@in_group = nil | ||
end | ||
|
||
def print | ||
@packages.each do |package| | ||
next if package[:group] | ||
version_op, version_value = canonicalize_version(package[:version]) | ||
puts "#{package[:name]} #{version_op} #{version_value}" | ||
end | ||
end | ||
|
||
def canonicalize_version(version) | ||
if version.nil? | ||
return ['>=', '0'] | ||
end | ||
unless version =~ /^([>=~]*)(\d.+)$/ | ||
raise ArgumentError, "Invalid version specification: #{version}" | ||
end | ||
op, value = $1, $2 | ||
if op.empty? | ||
op = '=' | ||
end | ||
return [op, value] | ||
end | ||
end | ||
|
||
if (file = ARGV.shift) && file != '-' | ||
text = File.read(file) | ||
else | ||
file = '<stdin>' | ||
text = STDIN.read | ||
end | ||
|
||
parser = GemfileParser.new | ||
parser.parse(text, file) | ||
parser.print |