aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bundler/definition.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler/definition.rb')
-rw-r--r--lib/bundler/definition.rb129
1 files changed, 32 insertions, 97 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 2aa86847..eb23042d 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -3,124 +3,59 @@ require "digest/sha1"
# TODO: In the 0.10 release, there shouldn't be a locked subclass of Definition
module Bundler
class Definition
- def self.from_gemfile(gemfile)
+ attr_reader :dependencies, :sources, :locked_specs
+
+ def self.build(gemfile, lockfile)
gemfile = Pathname.new(gemfile).expand_path
unless gemfile.file?
raise GemfileNotFound, "#{gemfile} not found"
end
- Dsl.evaluate(gemfile)
+ # TODO: move this back into DSL
+ builder = Dsl.new
+ builder.instance_eval(File.read(gemfile.to_s), gemfile.to_s, 1)
+ builder.to_definition(lockfile)
end
- def self.from_lock(lockfile, check = true)
- return nil unless lockfile.exist?
-
- locked_definition = Locked.new(YAML.load_file(lockfile))
+ def initialize(lockfile, dependencies, sources)
+ @dependencies, @sources = dependencies, sources
- if check
- hash = Digest::SHA1.hexdigest(File.read("#{Bundler.root}/Gemfile"))
- unless locked_definition.hash == hash
- raise GemfileChanged, "You changed your Gemfile after locking. Please relock using `bundle lock`"
- end
+ if lockfile && File.exists?(lockfile)
+ locked = LockfileParser.new(File.read(lockfile))
+ @locked_deps = locked.dependencies
+ @locked_specs = SpecSet.new(locked.specs)
+ else
+ @locked_deps = []
+ @locked_specs = SpecSet.new([])
end
-
- locked_definition
end
- def self.flexdef(gemfile, lockfile)
- Flex.new(from_gemfile(gemfile), from_lock(lockfile, false))
- end
-
- attr_reader :dependencies, :sources
-
- alias resolved_dependencies dependencies
-
- def initialize(dependencies, sources)
- @dependencies = dependencies
- @sources = sources
+ # TODO: OMG LOL
+ def resolved_dependencies
+ locked_specs_as_deps + dependencies
end
def groups
dependencies.map { |d| d.groups }.flatten.uniq
end
- class Flex
- def initialize(gemfile, lockfile)
- @gemfile = gemfile
- @lockfile = lockfile
- end
-
- def dependencies
- @gemfile.dependencies
- end
+ # We have the dependencies from Gemfile.lock and the dependencies from the
+ # Gemfile. Here, we are finding a list of all dependencies that were
+ # originally present in the Gemfile that still satisfy the requirements
+ # of the dependencies in the Gemfile.lock
+ #
+ # 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
- def sources
- @gemfile.sources
+ @dependencies.each do |dep|
+ next if deps.include?(dep)
+ deps << dep if @locked_specs.any? { |s| s.satisfies?(dep) }
end
- def groups
- dependencies.map { |d| d.groups }.flatten.uniq
- end
-
- def resolved_dependencies
- @resolved_dependencies ||= begin
- if @lockfile
- # Build a list of gems that have been removed from the gemfile
- # but are still listed in the lockfile
- removed_deps = @lockfile.dependencies.select do |d|
- dependencies.all? { |d2| d2.name != d.name }
- end
-
- # Take the lockfile, remove the gems that are in the previously
- # built list of removed gems, and keep what's left over
- new_deps = @lockfile.resolved_dependencies.reject do |d|
- removed_deps.any? { |d2| d.name == d2.name }
- end
-
- # Add gems that have been added to the gemfile
- dependencies.each do |d|
- next if new_deps.any? {|new_dep| new_dep.name == d.name }
- new_deps << d
- end
-
- new_deps
- else
- dependencies
- end
- end
- end
- end
-
- class Locked < Definition
- def initialize(details)
- @details = details
- end
-
- def hash
- @details["hash"]
- end
-
- def sources
- @sources ||= @details["sources"].map do |args|
- name, options = args.to_a.flatten
- Bundler::Source.const_get(name).new(options)
- end
- end
-
- def resolved_dependencies
- @resolved_dependencies ||= @details["specs"].map do |args|
- name, details = args.to_a.flatten
- details["source"] = sources[details["source"]] if details.include?("source")
- Bundler::Dependency.new(name, details.delete("version"), details)
- end
- end
-
- def dependencies
- @dependencies ||= @details["dependencies"].map do |opts|
- Bundler::Dependency.new(opts.delete("name"), opts.delete("version"), opts)
- end
- end
+ @locked_specs.for(deps).map { |s| Gem::Dependency.new(s.name, s.version) }
end
end
end