aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorCarl Lerche <carllerche@mac.com>2010-06-01 17:05:12 -0700
committerCarl Lerche <carllerche@mac.com>2010-06-01 21:46:33 -0700
commit0ffe385f5889d3cb45dfd1d7cb4d95ad8e786df3 (patch)
tree7e157fe863656854ac5836bcb06989c4c729ff98 /lib
parent33f8e7d73077d4f8b57387ec44887d0a7f70594f (diff)
downloadbundler-0ffe385f5889d3cb45dfd1d7cb4d95ad8e786df3.tar.gz
wip
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler/definition.rb39
-rw-r--r--lib/bundler/index.rb6
-rw-r--r--lib/bundler/lazy_specification.rb34
-rw-r--r--lib/bundler/lockfile_parser.rb6
-rw-r--r--lib/bundler/resolver.rb6
-rw-r--r--lib/bundler/rubygems_ext.rb6
-rw-r--r--lib/bundler/source.rb1
7 files changed, 64 insertions, 34 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index c2de990b..b332f26c 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -3,7 +3,7 @@ require "digest/sha1"
# TODO: In the 0.10 release, there shouldn't be a locked subclass of Definition
module Bundler
class Definition
- attr_reader :dependencies, :sources, :locked_specs, :platforms
+ attr_reader :dependencies, :sources, :platforms
def self.build(gemfile, lockfile)
gemfile = Pathname.new(gemfile).expand_path
@@ -48,7 +48,7 @@ module Bundler
source.unlock! if source.respond_to?(:unlock!)
# Add all the spec names that are part of the source to unlock
- @unlock.concat locked_specs.
+ @unlock.concat @locked_specs.
select { |s| s.source == source }.
map { |s| s.name }
@@ -84,17 +84,6 @@ module Bundler
sources.length == 1 && sources.first.remotes.empty?
end
- # TODO: OMG LOL
- def resolver_dependencies
- @resolver_dependencies ||= begin
- deps = locked_specs_as_deps
- dependencies.each do |dep|
- deps << dep unless deps.any? { |d| d.name == dep.name }
- end
- deps
- end
- end
-
def groups
dependencies.map { |d| d.groups }.flatten.uniq
end
@@ -172,21 +161,16 @@ module Bundler
#
# This allows us to add on the *new* requirements in the Gemfile and make
# sure that the changes result in a conservative update to the Gemfile.lock.
- def locked_specs_as_deps
+ def locked_specs
deps = []
+
@dependencies.each do |dep|
if in_locked_deps?(dep) || satisfies_locked_spec?(dep)
deps << dep
end
end
- @locked_specs.for(deps, @unlock).map do |s|
- dep = Gem::Dependency.new(s.name, s.version)
- @locked_deps.each do |d|
- dep.source = d.source if d.name == dep.name
- end
- dep
- end
+ @locked_specs.for(deps, @unlock)
end
def in_locked_deps?(dep)
@@ -201,25 +185,30 @@ module Bundler
def resolve(type, idx)
source_requirements = {}
- resolver_dependencies.each do |dep|
+ dependencies.each do |dep|
next unless dep.source
source_requirements[dep.name] = dep.source.send(type)
end
# Run a resolve against the locally available gems
- Resolver.resolve(resolver_dependencies, idx, source_requirements)
+ specs = Resolver.resolve(dependencies, idx, source_requirements, locked_specs)
+ specs.each do |spec|
+ next unless spec.is_a?(LazySpecification)
+ spec.__materialize__(spec.source.send(type))
+ end
+ specs
end
def resolve_remote_specs
# An ambiguous dependency is any dependency that does not have
# a requirement on an explicit version. If there are any, then
# we must do a remote resolve.
- if resolver_dependencies.any? { |d| ambiguous?(d) }
+ if dependencies.any? { |d| ambiguous?(d) }
return resolve(:specs, remote_index)
end
# Simple logic for now. Can improve later.
- if specs.length == resolver_dependencies.length
+ if specs.length == dependencies.length
return specs
else
return resolve(:specs, remote_index)
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index ca3a3ec9..95c6d70e 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -25,7 +25,7 @@ module Bundler
def search(query)
case query
- when Gem::Specification, RemoteSpecification then search_by_spec(query)
+ when Gem::Specification, RemoteSpecification, LazySpecification then search_by_spec(query)
when String then @specs[query]
else search_by_dependency(query)
end
@@ -68,7 +68,9 @@ module Bundler
private
def search_by_spec(spec)
- @specs[spec.name].select { |s| s.version == spec.version && s.platform == spec.platform }
+ @specs[spec.name].select do |s|
+ s.version == spec.version && s.platform == spec.platform
+ end
end
def search_by_dependency(dependency)
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index e7cc05fc..fde443dd 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -3,18 +3,48 @@ require "rubygems/spec_fetcher"
module Bundler
class LazySpecification
- attr_reader :name, :version, :dependencies
+ attr_reader :name, :version, :dependencies, :platform
attr_accessor :source
- def initialize(name, version)
+ def initialize(name, version, platform)
@name = name
@version = version
@dependencies = []
+ @platform = platform
@source = nil
end
+ def full_name
+ if platform == Gem::Platform::RUBY or platform.nil? then
+ "#{@name}-#{@version}"
+ else
+ "#{@name}-#{@version}-#{platform}"
+ end
+ end
+
def satisfies?(dependency)
@name == dependency.name && dependency.requirement.satisfied_by?(Gem::Version.new(@version))
end
+
+ def __materialize__(index)
+ @specification = index.search(self).first
+ raise "Could not materialize #{full_name}" unless @specification
+ end
+
+ def respond_to?(*args)
+ super || @specification.respond_to?(*args)
+ end
+
+ private
+
+ def method_missing(method, *args, &blk)
+ if Gem::Specification.new.respond_to?(method)
+ raise "LazySpecification has not been materialized yet" unless @specification
+ @specification.send(method, *args, &blk)
+ else
+ super
+ end
+ end
+
end
end \ No newline at end of file
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index 2178939a..c85d8130 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -50,7 +50,7 @@ module Bundler
end
end
- NAME_VERSION = '(?! )(.*?)(?: \((.*)\))?'
+ NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'
def parse_dependency(line)
if line =~ %r{^ {2}#{NAME_VERSION}(!)?$}
@@ -77,7 +77,9 @@ module Bundler
def parse_spec(line)
if line =~ %r{^ {4}#{NAME_VERSION}$}
- @current_spec = LazySpecification.new($1, $2)
+ name, version = $1, Gem::Version.new($2)
+ platform = $3 ? Gem::Platform.new($3) : Gem::Platform::RUBY
+ @current_spec = LazySpecification.new(name, version, platform)
@current_spec.source = @current_source
@specs << @current_spec
elsif line =~ %r{^ {6}#{NAME_VERSION}$}
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index fddae444..aa39a6ad 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -34,10 +34,12 @@ module Bundler
# ==== Returns
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
# collection of gemspecs is returned. Otherwise, nil is returned.
- def self.resolve(requirements, index, source_requirements = {})
+ def self.resolve(requirements, index, source_requirements = {}, base = [])
resolver = new(index, source_requirements)
result = catch(:success) do
- resolver.resolve(requirements, {})
+ activated = {}
+ base.each { |s| activated[s.name] = s }
+ resolver.resolve(requirements, activated)
output = resolver.errors.inject("") do |o, (conflict, (origin, requirement))|
if origin
o << " Conflict on: #{conflict.inspect}:\n"
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index e8936c9a..94f8a12d 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -48,7 +48,11 @@ module Gem
end
def to_lock
- out = " #{name} (#{version})\n"
+ if platform == Gem::Platform::RUBY or platform.nil?
+ out = " #{name} (#{version})\n"
+ else
+ out = " #{name} (#{version}-#{platform})\n"
+ end
dependencies.sort_by {|d| d.name }.each do |dep|
next if dep.type == :development
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index 9afb4ce8..787233aa 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -301,6 +301,7 @@ module Bundler
s.name = @name
s.source = self
s.version = Gem::Version.new(@version)
+ s.platform = Gem::Platform::RUBY
s.summary = "Fake gemspec for #{@name}"
s.relative_loaded_from = "#{@name}.gemspec"
if path.join("bin").exist?