bundler-maglev- 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +32 -0
  3. data/CHANGELOG.md +805 -0
  4. data/ISSUES.md +62 -0
  5. data/LICENSE +23 -0
  6. data/README.md +29 -0
  7. data/Rakefile +212 -0
  8. data/UPGRADING.md +103 -0
  9. data/bin/bundle +22 -0
  10. data/bundler.gemspec +30 -0
  11. data/lib/bundler.rb +286 -0
  12. data/lib/bundler/capistrano.rb +11 -0
  13. data/lib/bundler/cli.rb +520 -0
  14. data/lib/bundler/definition.rb +438 -0
  15. data/lib/bundler/dependency.rb +134 -0
  16. data/lib/bundler/deployment.rb +58 -0
  17. data/lib/bundler/dsl.rb +257 -0
  18. data/lib/bundler/environment.rb +47 -0
  19. data/lib/bundler/gem_helper.rb +151 -0
  20. data/lib/bundler/gem_installer.rb +9 -0
  21. data/lib/bundler/gem_tasks.rb +2 -0
  22. data/lib/bundler/graph.rb +130 -0
  23. data/lib/bundler/index.rb +138 -0
  24. data/lib/bundler/installer.rb +97 -0
  25. data/lib/bundler/lazy_specification.rb +74 -0
  26. data/lib/bundler/lockfile_parser.rb +108 -0
  27. data/lib/bundler/remote_specification.rb +59 -0
  28. data/lib/bundler/resolver.rb +464 -0
  29. data/lib/bundler/rubygems_ext.rb +237 -0
  30. data/lib/bundler/rubygems_integration.rb +349 -0
  31. data/lib/bundler/runtime.rb +152 -0
  32. data/lib/bundler/settings.rb +115 -0
  33. data/lib/bundler/setup.rb +23 -0
  34. data/lib/bundler/shared_helpers.rb +71 -0
  35. data/lib/bundler/source.rb +708 -0
  36. data/lib/bundler/spec_set.rb +135 -0
  37. data/lib/bundler/templates/Executable +16 -0
  38. data/lib/bundler/templates/Gemfile +4 -0
  39. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  40. data/lib/bundler/templates/newgem/Rakefile.tt +1 -0
  41. data/lib/bundler/templates/newgem/bin/newgem.tt +3 -0
  42. data/lib/bundler/templates/newgem/gitignore.tt +4 -0
  43. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +9 -0
  44. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  45. data/lib/bundler/templates/newgem/newgem.gemspec.tt +24 -0
  46. data/lib/bundler/ui.rb +73 -0
  47. data/lib/bundler/vendor/thor.rb +358 -0
  48. data/lib/bundler/vendor/thor/actions.rb +314 -0
  49. data/lib/bundler/vendor/thor/actions/create_file.rb +105 -0
  50. data/lib/bundler/vendor/thor/actions/create_link.rb +57 -0
  51. data/lib/bundler/vendor/thor/actions/directory.rb +93 -0
  52. data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
  53. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +270 -0
  54. data/lib/bundler/vendor/thor/actions/inject_into_file.rb +109 -0
  55. data/lib/bundler/vendor/thor/base.rb +576 -0
  56. data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
  57. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  58. data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
  59. data/lib/bundler/vendor/thor/error.rb +30 -0
  60. data/lib/bundler/vendor/thor/group.rb +273 -0
  61. data/lib/bundler/vendor/thor/invocation.rb +168 -0
  62. data/lib/bundler/vendor/thor/parser.rb +4 -0
  63. data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
  64. data/lib/bundler/vendor/thor/parser/arguments.rb +161 -0
  65. data/lib/bundler/vendor/thor/parser/option.rb +120 -0
  66. data/lib/bundler/vendor/thor/parser/options.rb +175 -0
  67. data/lib/bundler/vendor/thor/rake_compat.rb +66 -0
  68. data/lib/bundler/vendor/thor/runner.rb +309 -0
  69. data/lib/bundler/vendor/thor/shell.rb +88 -0
  70. data/lib/bundler/vendor/thor/shell/basic.rb +302 -0
  71. data/lib/bundler/vendor/thor/shell/color.rb +108 -0
  72. data/lib/bundler/vendor/thor/shell/html.rb +121 -0
  73. data/lib/bundler/vendor/thor/task.rb +113 -0
  74. data/lib/bundler/vendor/thor/util.rb +229 -0
  75. data/lib/bundler/vendor/thor/version.rb +3 -0
  76. data/lib/bundler/vendored_thor.rb +7 -0
  77. data/lib/bundler/version.rb +6 -0
  78. data/lib/bundler/vlad.rb +11 -0
  79. data/man/bundle-config.ronn +90 -0
  80. data/man/bundle-exec.ronn +111 -0
  81. data/man/bundle-install.ronn +317 -0
  82. data/man/bundle-package.ronn +59 -0
  83. data/man/bundle-update.ronn +176 -0
  84. data/man/bundle.ronn +80 -0
  85. data/man/gemfile.5.ronn +284 -0
  86. data/man/index.txt +6 -0
  87. data/spec/bundler/gem_helper_spec.rb +143 -0
  88. data/spec/cache/gems_spec.rb +230 -0
  89. data/spec/cache/git_spec.rb +12 -0
  90. data/spec/cache/path_spec.rb +27 -0
  91. data/spec/cache/platform_spec.rb +57 -0
  92. data/spec/install/deploy_spec.rb +197 -0
  93. data/spec/install/deprecated_spec.rb +37 -0
  94. data/spec/install/gems/c_ext_spec.rb +48 -0
  95. data/spec/install/gems/env_spec.rb +107 -0
  96. data/spec/install/gems/flex_spec.rb +313 -0
  97. data/spec/install/gems/groups_spec.rb +259 -0
  98. data/spec/install/gems/packed_spec.rb +84 -0
  99. data/spec/install/gems/platform_spec.rb +192 -0
  100. data/spec/install/gems/resolving_spec.rb +72 -0
  101. data/spec/install/gems/simple_case_spec.rb +770 -0
  102. data/spec/install/gems/sudo_spec.rb +74 -0
  103. data/spec/install/gems/win32_spec.rb +26 -0
  104. data/spec/install/gemspec_spec.rb +125 -0
  105. data/spec/install/git_spec.rb +570 -0
  106. data/spec/install/invalid_spec.rb +35 -0
  107. data/spec/install/path_spec.rb +405 -0
  108. data/spec/install/upgrade_spec.rb +26 -0
  109. data/spec/lock/git_spec.rb +35 -0
  110. data/spec/lock/lockfile_spec.rb +739 -0
  111. data/spec/other/check_spec.rb +221 -0
  112. data/spec/other/config_spec.rb +40 -0
  113. data/spec/other/console_spec.rb +54 -0
  114. data/spec/other/exec_spec.rb +248 -0
  115. data/spec/other/ext_spec.rb +37 -0
  116. data/spec/other/help_spec.rb +39 -0
  117. data/spec/other/init_spec.rb +40 -0
  118. data/spec/other/newgem_spec.rb +46 -0
  119. data/spec/other/open_spec.rb +35 -0
  120. data/spec/other/show_spec.rb +82 -0
  121. data/spec/quality_spec.rb +62 -0
  122. data/spec/resolver/basic_spec.rb +20 -0
  123. data/spec/resolver/platform_spec.rb +82 -0
  124. data/spec/runtime/executable_spec.rb +110 -0
  125. data/spec/runtime/load_spec.rb +107 -0
  126. data/spec/runtime/platform_spec.rb +90 -0
  127. data/spec/runtime/require_spec.rb +231 -0
  128. data/spec/runtime/setup_spec.rb +730 -0
  129. data/spec/runtime/with_clean_env_spec.rb +15 -0
  130. data/spec/spec_helper.rb +92 -0
  131. data/spec/support/builders.rb +597 -0
  132. data/spec/support/helpers.rb +239 -0
  133. data/spec/support/indexes.rb +112 -0
  134. data/spec/support/matchers.rb +77 -0
  135. data/spec/support/path.rb +71 -0
  136. data/spec/support/platforms.rb +53 -0
  137. data/spec/support/ruby_ext.rb +20 -0
  138. data/spec/support/rubygems_ext.rb +37 -0
  139. data/spec/support/rubygems_hax/platform.rb +11 -0
  140. data/spec/support/sudo.rb +21 -0
  141. data/spec/update/gems_spec.rb +122 -0
  142. data/spec/update/git_spec.rb +196 -0
  143. data/spec/update/source_spec.rb +51 -0
  144. metadata +296 -0
@@ -0,0 +1,438 @@
1
+ require "digest/sha1"
2
+
3
+ module Bundler
4
+ class Definition
5
+ include GemHelpers
6
+
7
+ attr_reader :dependencies, :platforms, :sources
8
+
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
19
+
20
+ =begin
21
+ How does the new system work?
22
+ ===
23
+ * Load information from Gemfile and Lockfile
24
+ * Invalidate stale locked specs
25
+ * All specs from stale source are stale
26
+ * All specs that are reachable only through a stale
27
+ dependency are stale.
28
+ * If all fresh dependencies are satisfied by the locked
29
+ specs, then we can try to resolve locally.
30
+ =end
31
+
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
74
+
75
+ def resolve_with_cache!
76
+ raise "Specs already loaded" if @specs
77
+ @sources.each { |s| s.cached! }
78
+ specs
79
+ end
80
+
81
+ def resolve_remotely!
82
+ raise "Specs already loaded" if @specs
83
+ @remote = true
84
+ @sources.each { |s| s.remote! }
85
+ specs
86
+ end
87
+
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
101
+
102
+ def new_specs
103
+ specs - @locked_specs
104
+ end
105
+
106
+ def removed_specs
107
+ @locked_specs - specs
108
+ end
109
+
110
+ def new_platform?
111
+ @new_platform
112
+ end
113
+
114
+ def missing_specs
115
+ missing = []
116
+ resolve.materialize(requested_dependencies, missing)
117
+ missing
118
+ end
119
+
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
127
+
128
+ def current_dependencies
129
+ dependencies.reject { |d| !d.should_include? }
130
+ end
131
+
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
137
+
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
155
+
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
163
+
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
171
+
172
+ def no_sources?
173
+ @sources.length == 1 && @sources.first.remotes.empty?
174
+ end
175
+
176
+ def groups
177
+ dependencies.map { |d| d.groups }.flatten.uniq
178
+ end
179
+
180
+ def lock(file)
181
+ contents = to_lock
182
+
183
+ # Convert to \r\n if the existing lock has them
184
+ # i.e., Windows with `git config core.autocrlf=true`
185
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
186
+
187
+ return if @lockfile_contents == contents
188
+
189
+ if Bundler.settings[:frozen]
190
+ # TODO: Warn here if we got here.
191
+ return
192
+ end
193
+
194
+ File.open(file, 'wb'){|f| f.puts(contents) }
195
+ end
196
+
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
237
+
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" \
242
+ "your Gemfile. Run `bundle install` elsewhere and add the\n" \
243
+ "updated Gemfile.lock to version control."
244
+
245
+ unless explicit_flag
246
+ msg += "\n\nIf this is a development machine, remove the Gemfile " \
247
+ "freeze \nby running `bundle install --no-deployment`."
248
+ end
249
+
250
+ added = []
251
+ deleted = []
252
+ changed = []
253
+
254
+ if @locked_sources != @sources
255
+ new_sources = @sources - @locked_sources
256
+ deleted_sources = @locked_sources - @sources
257
+
258
+ if new_sources.any?
259
+ added.concat new_sources.map { |source| "* source: #{source}" }
260
+ end
261
+
262
+ if deleted_sources.any?
263
+ deleted.concat deleted_sources.map { |source| "* source: #{source}" }
264
+ end
265
+
266
+ changes = true
267
+ end
268
+
269
+ both_sources = Hash.new { |h,k| h[k] = ["no specified source", "no specified source"] }
270
+ @dependencies.each { |d| both_sources[d.name][0] = d.source if d.source }
271
+ @locked_deps.each { |d| both_sources[d.name][1] = d.source if d.source }
272
+ both_sources.delete_if { |k,v| v[0] == v[1] }
273
+
274
+ if @dependencies != @locked_deps
275
+ new_deps = @dependencies - @locked_deps
276
+ deleted_deps = @locked_deps - @dependencies
277
+
278
+ if new_deps.any?
279
+ added.concat new_deps.map { |d| "* #{pretty_dep(d)}" }
280
+ end
281
+
282
+ if deleted_deps.any?
283
+ deleted.concat deleted_deps.map { |d| "* #{pretty_dep(d)}" }
284
+ end
285
+
286
+ both_sources.each do |name, sources|
287
+ changed << "* #{name} from `#{sources[0]}` to `#{sources[1]}`"
288
+ end
289
+
290
+ changes = true
291
+ end
292
+
293
+ msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
294
+ msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
295
+ msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
296
+ msg << "\n"
297
+
298
+ raise ProductionError, msg if added.any? || deleted.any? || changed.any?
299
+ end
300
+
301
+ private
302
+
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
309
+
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
326
+
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
334
+
335
+ # Remove elements from the locked specs that are expired. This will most
336
+ # commonly happen if the Gemfile has changed since the lockfile was last
337
+ # generated
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
401
+
402
+ def in_locked_deps?(dep, d)
403
+ d && dep.source == d.source
404
+ end
405
+
406
+ def satisfies_locked_spec?(dep)
407
+ @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source == dep.source) }
408
+ end
409
+
410
+ def expanded_dependencies
411
+ @expanded_dependencies ||= expand_dependencies(dependencies, @remote)
412
+ end
413
+
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
424
+
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
431
+
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
437
+ end
438
+ end
@@ -0,0 +1,134 @@
1
+ require 'rubygems/dependency'
2
+ require 'bundler/shared_helpers'
3
+ require 'bundler/rubygems_ext'
4
+
5
+ module Bundler
6
+ class Dependency < Gem::Dependency
7
+ attr_reader :autorequire
8
+ attr_reader :groups
9
+ attr_reader :platforms
10
+
11
+ PLATFORM_MAP = {
12
+ :ruby => Gem::Platform::RUBY,
13
+ :ruby_18 => Gem::Platform::RUBY,
14
+ :ruby_19 => Gem::Platform::RUBY,
15
+ :mri => Gem::Platform::RUBY,
16
+ :mri_18 => Gem::Platform::RUBY,
17
+ :mri_19 => Gem::Platform::RUBY,
18
+ :rbx => Gem::Platform::RUBY,
19
+ :jruby => Gem::Platform::JAVA,
20
+ :mswin => Gem::Platform::MSWIN,
21
+ :mingw => Gem::Platform::MINGW,
22
+ :mingw_18 => Gem::Platform::MINGW,
23
+ :mingw_19 => Gem::Platform::MINGW
24
+ }.freeze
25
+
26
+ def initialize(name, version, options = {}, &blk)
27
+ type = options["type"] || :runtime
28
+ super(name, version, type)
29
+
30
+ @autorequire = nil
31
+ @groups = Array(options["group"] || :default).map { |g| g.to_sym }
32
+ @source = options["source"]
33
+ @platforms = Array(options["platforms"])
34
+ @env = options["env"]
35
+
36
+ if options.key?('require')
37
+ @autorequire = Array(options['require'] || [])
38
+ end
39
+ end
40
+
41
+ def gem_platforms(valid_platforms)
42
+ return valid_platforms if @platforms.empty?
43
+
44
+ platforms = []
45
+ @platforms.each do |p|
46
+ platform = PLATFORM_MAP[p]
47
+ next unless valid_platforms.include?(platform)
48
+ platforms |= [platform]
49
+ end
50
+ platforms
51
+ end
52
+
53
+ def should_include?
54
+ current_env? && current_platform?
55
+ end
56
+
57
+ def current_env?
58
+ return true unless @env
59
+ if Hash === @env
60
+ @env.all? do |key, val|
61
+ ENV[key.to_s] && (String === val ? ENV[key.to_s] == val : ENV[key.to_s] =~ val)
62
+ end
63
+ else
64
+ ENV[@env.to_s]
65
+ end
66
+ end
67
+
68
+ def current_platform?
69
+ return true if @platforms.empty?
70
+ @platforms.any? { |p| send("#{p}?") }
71
+ end
72
+
73
+ def to_lock
74
+ out = super
75
+ out << '!' if source
76
+ out << "\n"
77
+ end
78
+
79
+ private
80
+
81
+ def ruby?
82
+ !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev")
83
+ end
84
+
85
+ def ruby_18?
86
+ ruby? && RUBY_VERSION < "1.9"
87
+ end
88
+
89
+ def ruby_19?
90
+ ruby? && RUBY_VERSION >= "1.9"
91
+ end
92
+
93
+ def mri?
94
+ !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby")
95
+ end
96
+
97
+ def mri_18?
98
+ mri? && RUBY_VERSION < "1.9"
99
+ end
100
+
101
+ def mri_19?
102
+ mri? && RUBY_VERSION >= "1.9"
103
+ end
104
+
105
+ def rbx?
106
+ ruby? && defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
107
+ end
108
+
109
+ def jruby?
110
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
111
+ end
112
+
113
+ def maglev?
114
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == "maglev"
115
+ end
116
+
117
+ def mswin?
118
+ Bundler::WINDOWS
119
+ end
120
+
121
+ def mingw?
122
+ Bundler::WINDOWS && Gem::Platform.local.os == "mingw32"
123
+ end
124
+
125
+ def mingw_18?
126
+ mingw? && RUBY_VERSION < "1.9"
127
+ end
128
+
129
+ def mingw_19?
130
+ mingw? && RUBY_VERSION >= "1.9"
131
+ end
132
+
133
+ end
134
+ end