Object
# File lib/bundler/definition.rb, line 9 9: def self.build(gemfile, lockfile, unlock) 10: unlock ||= {} 11: gemfile = Pathname.new(gemfile).expand_path 12: 13: unless gemfile.file? 14: raise GemfileNotFound, "#{gemfile} not found" 15: end 16: 17: Dsl.evaluate(gemfile, lockfile, unlock) 18: end
# File lib/bundler/definition.rb, line 32 32: def initialize(lockfile, dependencies, sources, unlock) 33: @dependencies, @sources, @unlock = dependencies, sources, unlock 34: @remote = false 35: @specs = nil 36: @lockfile_contents = "" 37: 38: if lockfile && File.exists?(lockfile) 39: @lockfile_contents = Bundler.read_file(lockfile) 40: locked = LockfileParser.new(@lockfile_contents) 41: @platforms = locked.platforms 42: 43: if unlock != true 44: @locked_deps = locked.dependencies 45: @locked_specs = SpecSet.new(locked.specs) 46: @locked_sources = locked.sources 47: else 48: @unlock = {} 49: @locked_deps = [] 50: @locked_specs = SpecSet.new([]) 51: @locked_sources = [] 52: end 53: else 54: @unlock = {} 55: @platforms = [] 56: @locked_deps = [] 57: @locked_specs = SpecSet.new([]) 58: @locked_sources = [] 59: end 60: 61: @unlock[:gems] ||= [] 62: @unlock[:sources] ||= [] 63: 64: current_platform = Bundler.rubygems.platforms.map { |p| generic(p) }.compact.last 65: @new_platform = !@platforms.include?(current_platform) 66: @platforms |= [current_platform] 67: 68: eager_unlock = expand_dependencies(@unlock[:gems]) 69: @unlock[:gems] = @locked_specs.for(eager_unlock).map { |s| s.name } 70: 71: converge_sources 72: converge_dependencies 73: end
# File lib/bundler/definition.rb, line 128 128: def current_dependencies 129: dependencies.reject { |d| !d.should_include? } 130: end
# File lib/bundler/definition.rb, line 238 238: def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false) 239: changes = false 240: 241: msg = "You are trying to install in deployment mode after changing\n" "your Gemfile. Run `bundle install` elsewhere and add the\n" "updated Gemfile.lock to version control." 242: 243: unless explicit_flag 244: msg += "\n\nIf this is a development machine, remove the Gemfile " "freeze \nby running `bundle install --no-deployment`." 245: end 246: 247: added = [] 248: deleted = [] 249: changed = [] 250: 251: if @locked_sources != @sources 252: new_sources = @sources - @locked_sources 253: deleted_sources = @locked_sources - @sources 254: 255: if new_sources.any? 256: added.concat new_sources.map { |source| "* source: #{source}" } 257: end 258: 259: if deleted_sources.any? 260: deleted.concat deleted_sources.map { |source| "* source: #{source}" } 261: end 262: 263: changes = true 264: end 265: 266: both_sources = Hash.new { |h,k| h[k] = ["no specified source", "no specified source"] } 267: @dependencies.each { |d| both_sources[d.name][0] = d.source if d.source } 268: @locked_deps.each { |d| both_sources[d.name][1] = d.source if d.source } 269: both_sources.delete_if { |k,v| v[0] == v[1] } 270: 271: if @dependencies != @locked_deps 272: new_deps = @dependencies - @locked_deps 273: deleted_deps = @locked_deps - @dependencies 274: 275: if new_deps.any? 276: added.concat new_deps.map { |d| "* #{pretty_dep(d)}" } 277: end 278: 279: if deleted_deps.any? 280: deleted.concat deleted_deps.map { |d| "* #{pretty_dep(d)}" } 281: end 282: 283: both_sources.each do |name, sources| 284: changed << "* #{name} from `#{sources[0]}` to `#{sources[1]}`" 285: end 286: 287: changes = true 288: end 289: 290: msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any? 291: msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any? 292: msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any? 293: msg << "\n" 294: 295: raise ProductionError, msg if added.any? || deleted.any? || changed.any? 296: end
# File lib/bundler/definition.rb, line 176 176: def groups 177: dependencies.map { |d| d.groups }.flatten.uniq 178: end
# File lib/bundler/definition.rb, line 156 156: def index 157: @index ||= Index.build do |idx| 158: @sources.each do |s| 159: idx.use s.specs 160: end 161: end 162: end
# File lib/bundler/definition.rb, line 180 180: def lock(file) 181: contents = to_lock 182: 183: return if @lockfile_contents == contents 184: 185: if Bundler.settings[:frozen] 186: # TODO: Warn here if we got here. 187: return 188: end 189: 190: # Convert to \r\n if the existing lock has them 191: # i.e., Windows with `git config core.autocrlf=true` 192: contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n") 193: 194: File.open(file, 'wb'){|f| f.puts(contents) } 195: end
# File lib/bundler/definition.rb, line 114 114: def missing_specs 115: missing = [] 116: resolve.materialize(requested_dependencies, missing) 117: missing 118: end
# File lib/bundler/definition.rb, line 110 110: def new_platform? 111: @new_platform 112: end
# File lib/bundler/definition.rb, line 102 102: def new_specs 103: specs - @locked_specs 104: end
# File lib/bundler/definition.rb, line 172 172: def no_sources? 173: @sources.length == 1 && @sources.first.remotes.empty? 174: end
# File lib/bundler/definition.rb, line 106 106: def removed_specs 107: @locked_specs - specs 108: end
# File lib/bundler/definition.rb, line 120 120: def requested_specs 121: @requested_specs ||= begin 122: groups = self.groups - Bundler.settings.without 123: groups.map! { |g| g.to_sym } 124: specs_for(groups) 125: end 126: end
# File lib/bundler/definition.rb, line 138 138: def resolve 139: @resolve ||= begin 140: if Bundler.settings[:frozen] 141: @locked_specs 142: else 143: last_resolve = converge_locked_specs 144: source_requirements = {} 145: dependencies.each do |dep| 146: next unless dep.source 147: source_requirements[dep.name] = dep.source.specs 148: end 149: 150: # Run a resolve against the locally available gems 151: last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve) 152: end 153: end 154: end
# File lib/bundler/definition.rb, line 81 81: def resolve_remotely! 82: raise "Specs already loaded" if @specs 83: @remote = true 84: @sources.each { |s| s.remote! } 85: specs 86: end
# File lib/bundler/definition.rb, line 75 75: def resolve_with_cache! 76: raise "Specs already loaded" if @specs 77: @sources.each { |s| s.cached! } 78: specs 79: end
# File lib/bundler/definition.rb, line 164 164: def rubygems_index 165: @rubygems_index ||= Index.build do |idx| 166: @sources.find_all{|s| s.is_a?(Source::Rubygems) }.each do |s| 167: idx.use s.specs 168: end 169: end 170: end
# File lib/bundler/definition.rb, line 88 88: def specs 89: @specs ||= begin 90: specs = resolve.materialize(requested_dependencies) 91: 92: unless specs["bundler"].any? 93: local = Bundler.settings[:frozen] ? rubygems_index : index 94: bundler = local.search(Gem::Dependency.new('bundler', VERSION)).last 95: specs["bundler"] = bundler if bundler 96: end 97: 98: specs 99: end 100: end
# File lib/bundler/definition.rb, line 132 132: def specs_for(groups) 133: deps = dependencies.select { |d| (d.groups & groups).any? } 134: deps.delete_if { |d| !d.should_include? } 135: specs.for(expand_dependencies(deps)) 136: end
# File lib/bundler/definition.rb, line 197 197: def to_lock 198: out = "" 199: 200: sorted_sources.each do |source| 201: # Add the source header 202: out << source.to_lock 203: # Find all specs for this source 204: resolve. 205: select { |s| s.source == source }. 206: # This needs to be sorted by full name so that 207: # gems with the same name, but different platform 208: # are ordered consistantly 209: sort_by { |s| s.full_name }. 210: each do |spec| 211: next if spec.name == 'bundler' 212: out << spec.to_lock 213: end 214: out << "\n" 215: end 216: 217: out << "PLATFORMS\n" 218: 219: platforms.map { |p| p.to_s }.sort.each do |p| 220: out << " #{p}\n" 221: end 222: 223: out << "\n" 224: out << "DEPENDENCIES\n" 225: 226: handled = [] 227: dependencies. 228: sort_by { |d| d.to_s }. 229: each do |dep| 230: next if handled.include?(dep.name) 231: out << dep.to_lock 232: handled << dep.name 233: end 234: 235: out 236: end
# File lib/bundler/definition.rb, line 327 327: def converge_dependencies 328: (@dependencies + @locked_deps).each do |dep| 329: if dep.source 330: dep.source = @sources.find { |s| dep.source == s } 331: end 332: end 333: end
Remove elements from the locked specs that are expired. This will most commonly happen if the Gemfile has changed since the lockfile was last generated
# File lib/bundler/definition.rb, line 338 338: def converge_locked_specs 339: deps = [] 340: 341: # Build a list of dependencies that are the same in the Gemfile 342: # and Gemfile.lock. If the Gemfile modified a dependency, but 343: # the gem in the Gemfile.lock still satisfies it, this is fine 344: # too. 345: @dependencies.each do |dep| 346: locked_dep = @locked_deps.find { |d| dep == d } 347: 348: if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep) 349: deps << dep 350: elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source) 351: @locked_specs.each do |s| 352: @unlock[:gems] << s.name if s.source == dep.source 353: end 354: 355: dep.source.unlock! if dep.source.respond_to?(:unlock!) 356: dep.source.specs.each { |s| @unlock[:gems] << s.name } 357: end 358: end 359: 360: converged = [] 361: @locked_specs.each do |s| 362: s.source = @sources.find { |src| s.source == src } 363: 364: # Don't add a spec to the list if its source is expired. For example, 365: # if you change a Git gem to Rubygems. 366: next if s.source.nil? || @unlock[:sources].include?(s.name) 367: # If the spec is from a path source and it doesn't exist anymore 368: # then we just unlock it. 369: 370: # Path sources have special logic 371: if s.source.instance_of?(Source::Path) 372: other = s.source.specs[s].first 373: 374: # If the spec is no longer in the path source, unlock it. This 375: # commonly happens if the version changed in the gemspec 376: next unless other 377: 378: deps2 = other.dependencies.select { |d| d.type != :development } 379: # If the dependencies of the path source have changed, unlock it 380: next unless s.dependencies.sort == deps2.sort 381: end 382: 383: converged << s 384: end 385: 386: resolve = SpecSet.new(converged) 387: resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems]) 388: diff = @locked_specs.to_a - resolve.to_a 389: 390: # Now, we unlock any sources that do not have anymore gems pinned to it 391: @sources.each do |source| 392: next unless source.respond_to?(:unlock!) 393: 394: unless resolve.any? { |s| s.source == source } 395: source.unlock! if !diff.empty? && diff.any? { |s| s.source == source } 396: end 397: end 398: 399: resolve 400: end
# File lib/bundler/definition.rb, line 310 310: def converge_sources 311: locked_gem = @locked_sources.find { |s| Source::Rubygems === s } 312: actual_gem = @sources.find { |s| Source::Rubygems === s } 313: 314: if locked_gem && actual_gem 315: locked_gem.merge_remotes actual_gem 316: end 317: 318: @sources.map! do |source| 319: @locked_sources.find { |s| s == source } || source 320: end 321: 322: @sources.each do |source| 323: source.unlock! if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name) 324: end 325: end
# File lib/bundler/definition.rb, line 414 414: def expand_dependencies(dependencies, remote = false) 415: deps = [] 416: dependencies.each do |dep| 417: dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name) 418: dep.gem_platforms(@platforms).each do |p| 419: deps << DepProxy.new(dep, p) if remote || p == generic(Gem::Platform.local) 420: end 421: end 422: deps 423: end
# File lib/bundler/definition.rb, line 410 410: def expanded_dependencies 411: @expanded_dependencies ||= expand_dependencies(dependencies, @remote) 412: end
# File lib/bundler/definition.rb, line 402 402: def in_locked_deps?(dep, d) 403: d && dep.source == d.source 404: end
# File lib/bundler/definition.rb, line 303 303: def pretty_dep(dep, source = false) 304: msg = "#{dep.name}" 305: msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default 306: msg << " from the `#{dep.source}` source" if source && dep.source 307: msg 308: end
# File lib/bundler/definition.rb, line 432 432: def requested_dependencies 433: groups = self.groups - Bundler.settings.without 434: groups.map! { |g| g.to_sym } 435: dependencies.reject { |d| !d.should_include? || (d.groups & groups).empty? } 436: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.