Object
# File lib/bundler/definition.rb, line 9 def self.build(gemfile, lockfile, unlock) unlock ||= {} gemfile = Pathname.new(gemfile).expand_path unless gemfile.file? raise GemfileNotFound, "#{gemfile} not found" end Dsl.evaluate(gemfile, lockfile, unlock) end
How does the new system work?
Load information from Gemfile and Lockfile
Invalidate stale locked specs
All specs from stale source are stale
All specs that are reachable only through a stale dependency are stale.
If all fresh dependencies are satisfied by the locked specs, then we can try to resolve locally.
# File lib/bundler/definition.rb, line 32 def initialize(lockfile, dependencies, sources, unlock) @dependencies, @sources, @unlock = dependencies, sources, unlock @remote = false @specs = nil @lockfile_contents = "" if lockfile && File.exists?(lockfile) @lockfile_contents = Bundler.read_file(lockfile) locked = LockfileParser.new(@lockfile_contents) @platforms = locked.platforms if unlock != true @locked_deps = locked.dependencies @locked_specs = SpecSet.new(locked.specs) @locked_sources = locked.sources else @unlock = {} @locked_deps = [] @locked_specs = SpecSet.new([]) @locked_sources = [] end else @unlock = {} @platforms = [] @locked_deps = [] @locked_specs = SpecSet.new([]) @locked_sources = [] end @unlock[:gems] ||= [] @unlock[:sources] ||= [] current_platform = Gem.platforms.map { |p| generic(p) }.compact.last @new_platform = !@platforms.include?(current_platform) @platforms |= [current_platform] eager_unlock = expand_dependencies(@unlock[:gems]) @unlock[:gems] = @locked_specs.for(eager_unlock).map { |s| s.name } converge_sources converge_dependencies end
# File lib/bundler/definition.rb, line 128 def current_dependencies dependencies.reject { |d| !d.should_include? } end
# File lib/bundler/definition.rb, line 238 def ensure_equivalent_gemfile_and_lockfile changes = false msg = "You have modified your Gemfile in development but did not check\n" "the resulting snapshot (Gemfile.lock) into version control" added = [] deleted = [] changed = [] if @locked_sources != @sources new_sources = @sources - @locked_sources deleted_sources = @locked_sources - @sources if new_sources.any? added.concat new_sources.map { |source| "* source: #{source}" } end if deleted_sources.any? deleted.concat deleted_sources.map { |source| "* source: #{source}" } end changes = true end both_sources = Hash.new { |h,k| h[k] = ["no specified source", "no specified source"] } @dependencies.each { |d| both_sources[d.name][0] = d.source if d.source } @locked_deps.each { |d| both_sources[d.name][1] = d.source if d.source } both_sources.delete_if { |k,v| v[0] == v[1] } if @dependencies != @locked_deps new_deps = @dependencies - @locked_deps deleted_deps = @locked_deps - @dependencies if new_deps.any? added.concat new_deps.map { |d| "* #{pretty_dep(d)}" } end if deleted_deps.any? deleted.concat deleted_deps.map { |d| "* #{pretty_dep(d)}" } end both_sources.each do |name, sources| changed << "* #{name} from `#{sources[0]}` to `#{sources[1]}`" end changes = true end msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any? msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any? msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any? raise ProductionError, msg if added.any? || deleted.any? || changed.any? end
# File lib/bundler/definition.rb, line 176 def groups dependencies.map { |d| d.groups }.flatten.uniq end
# File lib/bundler/definition.rb, line 156 def index @index ||= Index.build do |idx| @sources.each do |s| idx.use s.specs end end end
# File lib/bundler/definition.rb, line 180 def lock(file) contents = to_lock return if @lockfile_contents == contents if Bundler.settings[:frozen] # TODO: Warn here if we got here. return end # Convert to \r\n if the existing lock has them # i.e., Windows with `git config core.autocrlf=true` contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n") File.open(file, 'wb'){|f| f.puts(contents) } end
# File lib/bundler/definition.rb, line 114 def missing_specs missing = [] resolve.materialize(requested_dependencies, missing) missing end
# File lib/bundler/definition.rb, line 110 def new_platform? @new_platform end
# File lib/bundler/definition.rb, line 102 def new_specs specs - @locked_specs end
# File lib/bundler/definition.rb, line 172 def no_sources? @sources.length == 1 && @sources.first.remotes.empty? end
# File lib/bundler/definition.rb, line 106 def removed_specs @locked_specs - specs end
# File lib/bundler/definition.rb, line 120 def requested_specs @requested_specs ||= begin groups = self.groups - Bundler.settings.without groups.map! { |g| g.to_sym } specs_for(groups) end end
# File lib/bundler/definition.rb, line 138 def resolve @resolve ||= begin if Bundler.settings[:frozen] @locked_specs else last_resolve = converge_locked_specs source_requirements = {} dependencies.each do |dep| next unless dep.source source_requirements[dep.name] = dep.source.specs end # Run a resolve against the locally available gems last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve) end end end
# File lib/bundler/definition.rb, line 81 def resolve_remotely! raise "Specs already loaded" if @specs @remote = true @sources.each { |s| s.remote! } specs end
# File lib/bundler/definition.rb, line 75 def resolve_with_cache! raise "Specs already loaded" if @specs @sources.each { |s| s.cached! } specs end
# File lib/bundler/definition.rb, line 164 def rubygems_index @rubygems_index ||= Index.build do |idx| @sources.find_all{|s| s.is_a?(Source::Rubygems) }.each do |s| idx.use s.specs end end end
# File lib/bundler/definition.rb, line 88 def specs @specs ||= begin specs = resolve.materialize(requested_dependencies) unless specs["bundler"].any? local = Bundler.settings[:frozen] ? rubygems_index : index bundler = local.search(Gem::Dependency.new('bundler', VERSION)).last specs["bundler"] = bundler if bundler end specs end end
# File lib/bundler/definition.rb, line 132 def specs_for(groups) deps = dependencies.select { |d| (d.groups & groups).any? } deps.delete_if { |d| !d.should_include? } specs.for(expand_dependencies(deps)) end
# File lib/bundler/definition.rb, line 197 def to_lock out = "" sorted_sources.each do |source| # Add the source header out << source.to_lock # Find all specs for this source resolve. select { |s| s.source == source }. # This needs to be sorted by full name so that # gems with the same name, but different platform # are ordered consistantly sort_by { |s| s.full_name }. each do |spec| next if spec.name == 'bundler' out << spec.to_lock end out << "\n" end out << "PLATFORMS\n" platforms.map { |p| p.to_s }.sort.each do |p| out << " #{p}\n" end out << "\n" out << "DEPENDENCIES\n" handled = [] dependencies. sort_by { |d| d.name }. each do |dep| next if handled.include?(dep.name) out << dep.to_lock handled << dep.name end out end
Generated with the Darkfish Rdoc Generator 2.