aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Lerche <carllerche@mac.com>2010-06-01 21:36:46 -0700
committerCarl Lerche <carllerche@mac.com>2010-06-01 21:36:46 -0700
commit33f8e7d73077d4f8b57387ec44887d0a7f70594f (patch)
tree988fb87a28eaa1684127edb005b6422077d0448e
parent27c8e606cef18dd88de3998ec0b6c40efd6ee86d (diff)
downloadbundler-33f8e7d73077d4f8b57387ec44887d0a7f70594f.tar.gz
Merge locked sources with Gemfile sources
-rw-r--r--lib/bundler/definition.rb53
-rw-r--r--lib/bundler/source.rb33
2 files changed, 75 insertions, 11 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index d0e03ddd..c2de990b 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -23,15 +23,18 @@ module Bundler
if lockfile && File.exists?(lockfile)
locked = LockfileParser.new(File.read(lockfile))
- @platforms = locked.platforms
- @locked_deps = locked.dependencies
- @locked_specs = SpecSet.new(locked.specs)
- @sources = locked.sources
+ @platforms = locked.platforms
+ @locked_deps = locked.dependencies
+ @locked_specs = SpecSet.new(locked.specs)
+ @locked_sources = locked.sources
else
- @platforms = []
- @locked_deps = []
- @locked_specs = SpecSet.new([])
+ @platforms = []
+ @locked_deps = []
+ @locked_specs = SpecSet.new([])
+ @locked_sources = []
end
+
+ converge
end
def unlock!(what_to_unlock)
@@ -137,6 +140,24 @@ module Bundler
private
+ def converge
+ common = @locked_sources & @sources
+ fresh = @sources - common
+ stale = @locked_sources - common
+
+ @locked_specs.each do |s|
+ next unless stale.include?(s.source)
+ @unlock << s.name
+ end
+
+ @sources = common + fresh
+ @dependencies.each do |dep|
+ if dep.source && source = @sources.find { |s| dep.source == s }
+ dep.source == source
+ end
+ end
+ end
+
def sorted_sources
sources.sort_by do |s|
# Place GEM at the top
@@ -152,11 +173,11 @@ 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
- deps = @dependencies & @locked_deps
-
+ deps = []
@dependencies.each do |dep|
- next if deps.include?(dep)
- deps << dep if @locked_specs.any? { |s| s.satisfies?(dep) }
+ if in_locked_deps?(dep) || satisfies_locked_spec?(dep)
+ deps << dep
+ end
end
@locked_specs.for(deps, @unlock).map do |s|
@@ -168,6 +189,16 @@ module Bundler
end
end
+ def in_locked_deps?(dep)
+ @locked_deps.any? do |d|
+ dep == d && dep.source == d.source
+ end
+ end
+
+ def satisfies_locked_spec?(dep)
+ @locked_specs.any? { |s| s.satisfies?(dep) }
+ end
+
def resolve(type, idx)
source_requirements = {}
resolver_dependencies.each do |dep|
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index 681eb827..9afb4ce8 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -21,6 +21,16 @@ module Bundler
@spec_fetch_map = {}
end
+ def hash
+ Rubygems.hash
+ end
+
+ def eql?(o)
+ Rubygems === o
+ end
+
+ alias == eql?
+
# Not really needed, but it seems good to implement this method for interface
# consistency. Source name is mostly used to identify Path & Git sources
def name
@@ -241,6 +251,19 @@ module Bundler
"source at #{@path}"
end
+ def hash
+ self.class.hash
+ end
+
+ def eql?(o)
+ Path === o &&
+ path == o.path &&
+ name == o.name &&
+ version == o.version
+ end
+
+ alias == eql?
+
def name
File.basename(@path.to_s)
end
@@ -405,6 +428,16 @@ module Bundler
out << " specs:\n"
end
+ def eql?(o)
+ Git === o &&
+ uri == o.uri &&
+ ref == o.ref &&
+ name == o.name &&
+ version == o.version
+ end
+
+ alias == eql?
+
def to_s
ref = @options["ref"] ? shortref_for(@options["ref"]) : @ref
"#{@uri} (at #{ref})"