Parent

Included Modules

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:       # TODO: move this back into DSL
18:       builder = Dsl.new
19:       builder.instance_eval(Bundler.read_file(gemfile.to_s), gemfile.to_s, 1)
20:       builder.to_definition(lockfile, unlock)
21:     end
new(lockfile, dependencies, sources, unlock) click to toggle source
    # File lib/bundler/definition.rb, line 35
35:     def initialize(lockfile, dependencies, sources, unlock)
36:       @dependencies, @sources, @unlock = dependencies, sources, unlock
37:       @remote            = false
38:       @specs             = nil
39:       @lockfile_contents = ""
40: 
41:       if lockfile && File.exists?(lockfile)
42:         @lockfile_contents = Bundler.read_file(lockfile)
43:         locked = LockfileParser.new(@lockfile_contents)
44:         @platforms      = locked.platforms
45: 
46:         if unlock != true
47:           @locked_deps    = locked.dependencies
48:           @locked_specs   = SpecSet.new(locked.specs)
49:           @locked_sources = locked.sources
50:         else
51:           @unlock         = {}
52:           @locked_deps    = []
53:           @locked_specs   = SpecSet.new([])
54:           @locked_sources = []
55:         end
56:       else
57:         @unlock         = {}
58:         @platforms      = []
59:         @locked_deps    = []
60:         @locked_specs   = SpecSet.new([])
61:         @locked_sources = []
62:       end
63: 
64:       @unlock[:gems] ||= []
65:       @unlock[:sources] ||= []
66: 
67:       current_platform = Gem.platforms.map { |p| generic(p) }.compact.last
68:       @new_platform = !@platforms.include?(current_platform)
69:       @platforms |= [current_platform]
70: 
71:       eager_unlock = expand_dependencies(@unlock[:gems])
72:       @unlock[:gems] = @locked_specs.for(eager_unlock).map { |s| s.name }
73: 
74:       converge_sources
75:       converge_dependencies
76:     end

Public Instance Methods

current_dependencies() click to toggle source
     # File lib/bundler/definition.rb, line 130
130:     def current_dependencies
131:       dependencies.reject { |d| !d.should_include? }
132:     end
ensure_equivalent_gemfile_and_lockfile() click to toggle source
     # File lib/bundler/definition.rb, line 230
230:     def ensure_equivalent_gemfile_and_lockfile
231:       changes = false
232: 
233:       msg = "You have modified your Gemfile in development but did not check\n"              "the resulting snapshot (Gemfile.lock) into version control"
234: 
235:       added =   []
236:       deleted = []
237:       changed = []
238: 
239:       if @locked_sources != @sources
240:         new_sources = @sources - @locked_sources
241:         deleted_sources = @locked_sources - @sources
242: 
243:         if new_sources.any?
244:           added.concat new_sources.map { |source| "* source: #{source}" }
245:         end
246: 
247:         if deleted_sources.any?
248:           deleted.concat deleted_sources.map { |source| "* source: #{source}" }
249:         end
250: 
251:         changes = true
252:       end
253: 
254:       both_sources = Hash.new { |h,k| h[k] = ["no specified source", "no specified source"] }
255:       @dependencies.each { |d| both_sources[d.name][0] = d.source if d.source }
256:       @locked_deps.each  { |d| both_sources[d.name][1] = d.source if d.source }
257:       both_sources.delete_if { |k,v| v[0] == v[1] }
258: 
259:       if @dependencies != @locked_deps
260:         new_deps = @dependencies - @locked_deps
261:         deleted_deps = @locked_deps - @dependencies
262: 
263:         if new_deps.any?
264:           added.concat new_deps.map { |d| "* #{pretty_dep(d)}" }
265:         end
266: 
267:         if deleted_deps.any?
268:           deleted.concat deleted_deps.map { |d| "* #{pretty_dep(d)}" }
269:         end
270: 
271:         both_sources.each do |name, sources|
272:           changed << "* #{name} from `#{sources[0]}` to `#{sources[1]}`"
273:         end
274: 
275:         changes = true
276:       end
277: 
278:       msg << "\n\nYou have added to the Gemfile:\n"     << added.join("\n") if added.any?
279:       msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
280:       msg << "\n\nYou have changed in the Gemfile:\n"   << changed.join("\n") if changed.any?
281: 
282:       raise ProductionError, msg if added.any? || deleted.any? || changed.any?
283:     end
groups() click to toggle source
     # File lib/bundler/definition.rb, line 170
170:     def groups
171:       dependencies.map { |d| d.groups }.flatten.uniq
172:     end
index() click to toggle source
     # File lib/bundler/definition.rb, line 158
158:     def index
159:       @index ||= Index.build do |idx|
160:         @sources.each do |s|
161:           idx.use s.specs
162:         end
163:       end
164:     end
lock(file) click to toggle source
     # File lib/bundler/definition.rb, line 174
174:     def lock(file)
175:       contents = to_lock
176: 
177:       return if @lockfile_contents == contents
178: 
179:       if Bundler.settings[:frozen]
180:         # TODO: Warn here if we got here.
181:         return
182:       end
183: 
184:       File.open(file, 'wb') do |f|
185:         f.puts contents
186:       end
187:     end
missing_specs() click to toggle source
     # File lib/bundler/definition.rb, line 116
116:     def missing_specs
117:       missing = []
118:       resolve.materialize(requested_dependencies, missing)
119:       missing
120:     end
new_platform?() click to toggle source
     # File lib/bundler/definition.rb, line 112
112:     def new_platform?
113:       @new_platform
114:     end
new_specs() click to toggle source
     # File lib/bundler/definition.rb, line 104
104:     def new_specs
105:       specs - @locked_specs
106:     end
no_sources?() click to toggle source
     # File lib/bundler/definition.rb, line 166
166:     def no_sources?
167:       @sources.length == 1 && @sources.first.remotes.empty?
168:     end
removed_specs() click to toggle source
     # File lib/bundler/definition.rb, line 108
108:     def removed_specs
109:       @locked_specs - specs
110:     end
requested_specs() click to toggle source
     # File lib/bundler/definition.rb, line 122
122:     def requested_specs
123:       @requested_specs ||= begin
124:         groups = self.groups - Bundler.settings.without
125:         groups.map! { |g| g.to_sym }
126:         specs_for(groups)
127:       end
128:     end
resolve() click to toggle source
     # File lib/bundler/definition.rb, line 140
140:     def resolve
141:       @resolve ||= begin
142:         if Bundler.settings[:frozen]
143:           @locked_specs
144:         else
145:           last_resolve = converge_locked_specs
146:           source_requirements = {}
147:           dependencies.each do |dep|
148:             next unless dep.source
149:             source_requirements[dep.name] = dep.source.specs
150:           end
151: 
152:           # Run a resolve against the locally available gems
153:           last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve)
154:         end
155:       end
156:     end
resolve_remotely!() click to toggle source
    # File lib/bundler/definition.rb, line 84
84:     def resolve_remotely!
85:       raise "Specs already loaded" if @specs
86:       @remote = true
87:       @sources.each { |s| s.remote! }
88:       specs
89:     end
resolve_with_cache!() click to toggle source
    # File lib/bundler/definition.rb, line 78
78:     def resolve_with_cache!
79:       raise "Specs already loaded" if @specs
80:       @sources.each { |s| s.cached! }
81:       specs
82:     end
specs() click to toggle source
     # File lib/bundler/definition.rb, line 91
 91:     def specs
 92:       @specs ||= begin
 93:         specs = resolve.materialize(requested_dependencies)
 94: 
 95:         unless specs["bundler"].any?
 96:           bundler = index.search(Gem::Dependency.new('bundler', VERSION)).last
 97:           specs["bundler"] = bundler if bundler
 98:         end
 99: 
100:         specs
101:       end
102:     end
specs_for(groups) click to toggle source
     # File lib/bundler/definition.rb, line 134
134:     def specs_for(groups)
135:       deps = dependencies.select { |d| (d.groups & groups).any? }
136:       deps.delete_if { |d| !d.should_include? }
137:       specs.for(expand_dependencies(deps))
138:     end
to_lock() click to toggle source
     # File lib/bundler/definition.rb, line 189
189:     def to_lock
190:       out = ""
191: 
192:       sorted_sources.each do |source|
193:         # Add the source header
194:         out << source.to_lock
195:         # Find all specs for this source
196:         resolve.
197:           select  { |s| s.source == source }.
198:           # This needs to be sorted by full name so that
199:           # gems with the same name, but different platform
200:           # are ordered consistantly
201:           sort_by { |s| s.full_name }.
202:           each do |spec|
203:             next if spec.name == 'bundler'
204:             out << spec.to_lock
205:         end
206:         out << "\n"
207:       end
208: 
209:       out << "PLATFORMS\n"
210: 
211:       platforms.map { |p| p.to_s }.sort.each do |p|
212:         out << "  #{p}\n"
213:       end
214: 
215:       out << "\n"
216:       out << "DEPENDENCIES\n"
217: 
218:       handled = []
219:       dependencies.
220:         sort_by { |d| d.name }.
221:         each do |dep|
222:           next if handled.include?(dep.name)
223:           out << dep.to_lock
224:           handled << dep.name
225:       end
226: 
227:       out
228:     end

Private Instance Methods

converge_dependencies() click to toggle source
     # File lib/bundler/definition.rb, line 312
312:     def converge_dependencies
313:       (@dependencies + @locked_deps).each do |dep|
314:         if dep.source
315:           dep.source = @sources.find { |s| dep.source == s }
316:         end
317:       end
318:     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 323
323:     def converge_locked_specs
324:       deps = []
325: 
326:       # Build a list of dependencies that are the same in the Gemfile
327:       # and Gemfile.lock. If the Gemfile modified a dependency, but
328:       # the gem in the Gemfile.lock still satisfies it, this is fine
329:       # too.
330:       @dependencies.each do |dep|
331:         locked_dep = @locked_deps.find { |d| dep == d }
332: 
333:         if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
334:           deps << dep
335:         elsif dep.source.is_a?(Source::Path) && (!locked_dep || dep.source != locked_dep.source)
336:           @locked_specs.each do |s|
337:             @unlock[:gems] << s.name if s.source == dep.source
338:           end
339: 
340:           dep.source.unlock! if dep.source.respond_to?(:unlock!)
341:           dep.source.specs.each { |s| @unlock[:gems] << s.name }
342:         end
343:       end
344: 
345:       converged = []
346:       @locked_specs.each do |s|
347:         s.source = @sources.find { |src| s.source == src }
348: 
349:         # Don't add a spec to the list if its source is expired. For example,
350:         # if you change a Git gem to Rubygems.
351:         next if s.source.nil? || @unlock[:sources].include?(s.name)
352:         # If the spec is from a path source and it doesn't exist anymore
353:         # then we just unlock it.
354: 
355:         # Path sources have special logic
356:         if s.source.instance_of?(Source::Path)
357:           other = s.source.specs[s].first
358: 
359:           # If the spec is no longer in the path source, unlock it. This
360:           # commonly happens if the version changed in the gemspec
361:           next unless other
362:           # If the dependencies of the path source have changed, unlock it
363:           next unless s.dependencies.sort == other.dependencies.sort
364:         end
365: 
366:         converged << s
367:       end
368: 
369:       resolve = SpecSet.new(converged)
370:       resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems])
371:       diff    = @locked_specs.to_a - resolve.to_a
372: 
373:       # Now, we unlock any sources that do not have anymore gems pinned to it
374:       @sources.each do |source|
375:         next unless source.respond_to?(:unlock!)
376: 
377:         unless resolve.any? { |s| s.source == source }
378:           source.unlock! if diff.any? { |s| s.source == source }
379:         end
380:       end
381: 
382:       resolve
383:     end
converge_sources() click to toggle source
     # File lib/bundler/definition.rb, line 295
295:     def converge_sources
296:       locked_gem = @locked_sources.find { |s| Source::Rubygems === s }
297:       actual_gem = @sources.find { |s| Source::Rubygems === s }
298: 
299:       if locked_gem && actual_gem
300:         locked_gem.merge_remotes actual_gem
301:       end
302: 
303:       @sources.map! do |source|
304:         @locked_sources.find { |s| s == source } || source
305:       end
306: 
307:       @sources.each do |source|
308:         source.unlock! if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
309:       end
310:     end
expand_dependencies(dependencies, remote = false) click to toggle source
     # File lib/bundler/definition.rb, line 397
397:     def expand_dependencies(dependencies, remote = false)
398:       deps = []
399:       dependencies.each do |dep|
400:         dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
401:         dep.gem_platforms(@platforms).each do |p|
402:           deps << DepProxy.new(dep, p) if remote || p == generic(Gem::Platform.local)
403:         end
404:       end
405:       deps
406:     end
expanded_dependencies() click to toggle source
     # File lib/bundler/definition.rb, line 393
393:     def expanded_dependencies
394:       @expanded_dependencies ||= expand_dependencies(dependencies, @remote)
395:     end
in_locked_deps?(dep, d) click to toggle source
     # File lib/bundler/definition.rb, line 385
385:     def in_locked_deps?(dep, d)
386:       d && dep.source == d.source
387:     end
pretty_dep(dep, source = false) click to toggle source
     # File lib/bundler/definition.rb, line 288
288:     def pretty_dep(dep, source = false)
289:       msg  = "#{dep.name}"
290:       msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
291:       msg << " from the `#{dep.source}` source" if source && dep.source
292:       msg
293:     end
requested_dependencies() click to toggle source
     # File lib/bundler/definition.rb, line 415
415:     def requested_dependencies
416:       groups = self.groups - Bundler.settings.without
417:       groups.map! { |g| g.to_sym }
418:       dependencies.reject { |d| !d.should_include? || (d.groups & groups).empty? }
419:     end
satisfies_locked_spec?(dep) click to toggle source
     # File lib/bundler/definition.rb, line 389
389:     def satisfies_locked_spec?(dep)
390:       @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source == dep.source) }
391:     end
sorted_sources() click to toggle source
     # File lib/bundler/definition.rb, line 408
408:     def sorted_sources
409:       @sources.sort_by do |s|
410:         # Place GEM at the top
411:         [ s.is_a?(Source::Rubygems) ? 1 : 0, s.to_s ]
412:       end
413:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.