diff options
author | Carl Lerche <carllerche@mac.com> | 2010-06-01 17:05:12 -0700 |
---|---|---|
committer | Carl Lerche <carllerche@mac.com> | 2010-06-01 21:46:33 -0700 |
commit | 0ffe385f5889d3cb45dfd1d7cb4d95ad8e786df3 (patch) | |
tree | 7e157fe863656854ac5836bcb06989c4c729ff98 /lib | |
parent | 33f8e7d73077d4f8b57387ec44887d0a7f70594f (diff) | |
download | bundler-0ffe385f5889d3cb45dfd1d7cb4d95ad8e786df3.tar.gz |
wip
Diffstat (limited to 'lib')
-rw-r--r-- | lib/bundler/definition.rb | 39 | ||||
-rw-r--r-- | lib/bundler/index.rb | 6 | ||||
-rw-r--r-- | lib/bundler/lazy_specification.rb | 34 | ||||
-rw-r--r-- | lib/bundler/lockfile_parser.rb | 6 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 6 | ||||
-rw-r--r-- | lib/bundler/rubygems_ext.rb | 6 | ||||
-rw-r--r-- | lib/bundler/source.rb | 1 |
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? |