Parent

Included Modules

Class Index [+]

Quicksearch

Bundler::Definition

Attributes

dependencies[R]
platforms[R]
sources[R]

Public Class Methods

build(gemfile, lockfile, unlock) click to toggle source
    # 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
new(lockfile, dependencies, sources, unlock) click to toggle source
    # 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

Public Instance Methods

current_dependencies() click to toggle source
     # File lib/bundler/definition.rb, line 128
128:     def current_dependencies
129:       dependencies.reject { |d| !d.should_include? }
130:     end
ensure_equivalent_gemfile_and_lockfile(explicit_flag = false) click to toggle source
     # 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
groups() click to toggle source
     # File lib/bundler/definition.rb, line 176
176:     def groups
177:       dependencies.map { |d| d.groups }.flatten.uniq
178:     end
index() click to toggle source
     # 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
lock(file) click to toggle source
     # 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
missing_specs() click to toggle source
     # File lib/bundler/definition.rb, line 114
114:     def missing_specs
115:       missing = []
116:       resolve.materialize(requested_dependencies, missing)
117:       missing
118:     end
new_platform?() click to toggle source
     # File lib/bundler/definition.rb, line 110
110:     def new_platform?
111:       @new_platform
112:     end
new_specs() click to toggle source
     # File lib/bundler/definition.rb, line 102
102:     def new_specs
103:       specs - @locked_specs
104:     end
no_sources?() click to toggle source
     # File lib/bundler/definition.rb, line 172
172:     def no_sources?
173:       @sources.length == 1 && @sources.first.remotes.empty?
174:     end
removed_specs() click to toggle source
     # File lib/bundler/definition.rb, line 106
106:     def removed_specs
107:       @locked_specs - specs
108:     end
requested_specs() click to toggle source
     # 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
resolve() click to toggle source
     # 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
resolve_remotely!() click to toggle source
    # 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
resolve_with_cache!() click to toggle source
    # 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
rubygems_index() click to toggle source
     # 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
specs() click to toggle source
     # 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
specs_for(groups) click to toggle source
     # 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
to_lock() click to toggle source
     # 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

Private Instance Methods

converge_dependencies() click to toggle source
     # 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
converge_locked_specs() click to toggle source

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
converge_sources() click to toggle source
     # 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
expand_dependencies(dependencies, remote = false) click to toggle source
     # 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
expanded_dependencies() click to toggle source
     # File lib/bundler/definition.rb, line 410
410:     def expanded_dependencies
411:       @expanded_dependencies ||= expand_dependencies(dependencies, @remote)
412:     end
in_locked_deps?(dep, d) click to toggle source
     # File lib/bundler/definition.rb, line 402
402:     def in_locked_deps?(dep, d)
403:       d && dep.source == d.source
404:     end
pretty_dep(dep, source = false) click to toggle source
     # 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
requested_dependencies() click to toggle source
     # 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
satisfies_locked_spec?(dep) click to toggle source
     # File lib/bundler/definition.rb, line 406
406:     def satisfies_locked_spec?(dep)
407:       @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source == dep.source) }
408:     end
sorted_sources() click to toggle source
     # File lib/bundler/definition.rb, line 425
425:     def sorted_sources
426:       @sources.sort_by do |s|
427:         # Place GEM at the top
428:         [ s.is_a?(Source::Rubygems) ? 1 : 0, s.to_s ]
429:       end
430:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.