Class: Bundler::RubygemsIntegration
- Inherits:
-
Object
- Object
- Bundler::RubygemsIntegration
show all
- Defined in:
- lib/bundler/rubygems_integration.rb
Defined Under Namespace
Classes: AlmostModern, Ancient, Future, Legacy, Modern, MoreFuture, MoreModern, Transitional
Constant Summary
collapse
- EXT_LOCK =
Monitor.new
Class Method Summary
collapse
Instance Method Summary
collapse
-
#backport_base_dir ⇒ Object
This backports base_dir which replaces installation path Rubygems 1.8+.
-
#backport_cache_file ⇒ Object
-
#backport_segment_generation ⇒ Object
This backports the correct segment generation code from Rubygems 1.4+ by monkeypatching it into the method in Rubygems 1.3.6 and 1.3.7.
-
#backport_spec_file ⇒ Object
-
#backport_yaml_initialize ⇒ Object
This backport fixes the marshaling of @segments.
-
#bin_path(gem, bin, ver) ⇒ Object
-
#build(spec, skip_validation = false) ⇒ Object
-
#build_args ⇒ Object
-
#build_args=(args) ⇒ Object
-
#build_gem(gem_dir, spec) ⇒ Object
-
#clear_paths ⇒ Object
-
#config_map ⇒ Object
-
#configuration ⇒ Object
-
#download_gem(spec, uri, path) ⇒ Object
-
#ext_lock ⇒ Object
-
#fetch_all_remote_specs(remote) ⇒ Object
TODO: This is for older versions of Rubygems…
-
#fetch_prerelease_specs ⇒ Object
-
#fetch_specs(all, pre, &blk) ⇒ Object
-
#gem_bindir ⇒ Object
-
#gem_cache ⇒ Object
-
#gem_dir ⇒ Object
-
#gem_from_path(path, policy = nil) ⇒ Object
-
#gem_path ⇒ Object
-
#inflate(obj) ⇒ Object
-
#load_path_insert_index ⇒ Object
-
#loaded_gem_paths ⇒ Object
-
#loaded_specs(name) ⇒ Object
-
#mark_loaded(spec) ⇒ Object
-
#marshal_spec_dir ⇒ Object
-
#path(obj) ⇒ Object
-
#platforms ⇒ Object
-
#preserve_paths ⇒ Object
-
#provides?(req_str) ⇒ Boolean
-
#read_binary(path) ⇒ Object
-
#redefine_method(klass, method, &block) ⇒ Object
-
#replace_bin_path(specs) ⇒ Object
Used to make bin stubs that are not created by bundler work under bundler.
-
#replace_entrypoints(specs) ⇒ Object
Replace or hook into Rubygems to provide a bundlerized view of the world.
-
#replace_gem(specs) ⇒ Object
-
#replace_refresh ⇒ Object
Because Bundler has a static view of what specs are available, we don’t #refresh, so stub it out.
-
#repository_subdirectories ⇒ Object
-
#reverse_rubygems_kernel_mixin ⇒ Object
-
#ruby_engine ⇒ Object
-
#security_policies ⇒ Object
-
#security_policy_keys ⇒ Object
-
#set_installed_by_version(spec, installed_by_version = Gem::VERSION) ⇒ Object
-
#sources ⇒ Object
-
#sources=(val) ⇒ Object
-
#spec_cache_dirs ⇒ Object
-
#spec_from_gem(path, policy = nil) ⇒ Object
-
#spec_missing_extensions?(spec) ⇒ Boolean
-
#stub_source_index(specs) ⇒ Object
-
#ui=(obj) ⇒ Object
-
#user_home ⇒ Object
-
#validate(spec) ⇒ Object
-
#version ⇒ Object
-
#with_build_args(args) ⇒ Object
Class Method Details
.provides?(req_str) ⇒ Boolean
18
19
20
|
# File 'lib/bundler/rubygems_integration.rb', line 18
def self.provides?(req_str)
Gem::Requirement.new(req_str).satisfied_by?(version)
end
|
.version ⇒ Object
14
15
16
|
# File 'lib/bundler/rubygems_integration.rb', line 14
def self.version
@version ||= Gem::Version.new(Gem::VERSION)
end
|
Instance Method Details
#backport_base_dir ⇒ Object
This backports base_dir which replaces installation path Rubygems 1.8+
437
438
439
440
441
442
|
# File 'lib/bundler/rubygems_integration.rb', line 437
def backport_base_dir
redefine_method(Gem::Specification, :base_dir) do
return Gem.dir unless loaded_from
File.dirname File.dirname loaded_from
end
end
|
#backport_cache_file ⇒ Object
444
445
446
447
448
449
450
451
452
|
# File 'lib/bundler/rubygems_integration.rb', line 444
def backport_cache_file
redefine_method(Gem::Specification, :cache_dir) do
@cache_dir ||= File.join base_dir, "cache"
end
redefine_method(Gem::Specification, :cache_file) do
@cache_file ||= File.join cache_dir, "#{full_name}.gem"
end
end
|
#backport_segment_generation ⇒ Object
This backports the correct segment generation code from Rubygems 1.4+ by monkeypatching it into the method in Rubygems 1.3.6 and 1.3.7.
418
419
420
421
422
423
424
|
# File 'lib/bundler/rubygems_integration.rb', line 418
def backport_segment_generation
redefine_method(Gem::Version, :segments) do
@segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
/^\d+$/ =~ s ? s.to_i : s
end
end
end
|
#backport_spec_file ⇒ Object
454
455
456
457
458
459
460
461
462
|
# File 'lib/bundler/rubygems_integration.rb', line 454
def backport_spec_file
redefine_method(Gem::Specification, :spec_dir) do
@spec_dir ||= File.join base_dir, "specifications"
end
redefine_method(Gem::Specification, :spec_file) do
@spec_file ||= File.join spec_dir, "#{full_name}.gemspec"
end
end
|
#backport_yaml_initialize ⇒ Object
This backport fixes the marshaling of @segments.
427
428
429
430
431
432
433
|
# File 'lib/bundler/rubygems_integration.rb', line 427
def backport_yaml_initialize
redefine_method(Gem::Version, :yaml_initialize) do |_, map|
@version = map["version"]
@segments = nil
@hash = nil
end
end
|
#bin_path(gem, bin, ver) ⇒ Object
163
164
165
|
# File 'lib/bundler/rubygems_integration.rb', line 163
def bin_path(gem, bin, ver)
Gem.bin_path(gem, bin, ver)
end
|
#build(spec, skip_validation = false) ⇒ Object
256
257
258
259
|
# File 'lib/bundler/rubygems_integration.rb', line 256
def build(spec, skip_validation = false)
require "rubygems/builder"
Gem::Builder.new(spec).build
end
|
#build_args ⇒ Object
30
31
32
|
# File 'lib/bundler/rubygems_integration.rb', line 30
def build_args
Gem::Command.build_args
end
|
#build_args=(args) ⇒ Object
34
35
36
|
# File 'lib/bundler/rubygems_integration.rb', line 34
def build_args=(args)
Gem::Command.build_args = args
end
|
#build_gem(gem_dir, spec) ⇒ Object
261
262
263
|
# File 'lib/bundler/rubygems_integration.rb', line 261
def build_gem(gem_dir, spec)
build(spec)
end
|
#clear_paths ⇒ Object
159
160
161
|
# File 'lib/bundler/rubygems_integration.rb', line 159
def clear_paths
Gem.clear_paths
end
|
#config_map ⇒ Object
151
152
153
|
# File 'lib/bundler/rubygems_integration.rb', line 151
def config_map
Gem::ConfigMap
end
|
#configuration ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/bundler/rubygems_integration.rb', line 82
def configuration
require "bundler/psyched_yaml"
Gem.configuration
rescue Gem::SystemExitException, LoadError => e
Bundler.ui.error "#{e.class}: #{e.message}"
Bundler.ui.trace e
raise
rescue YamlLibrarySyntaxError => e
raise YamlSyntaxError.new(e, "Your RubyGems configuration, which is " \
"usually located in ~/.gemrc, contains invalid YAML syntax.")
end
|
#download_gem(spec, uri, path) ⇒ Object
265
266
267
268
269
|
# File 'lib/bundler/rubygems_integration.rb', line 265
def download_gem(spec, uri, path)
uri = Bundler.settings.mirror_for(uri)
fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
fetcher.download(spec, uri, path)
end
|
#ext_lock ⇒ Object
189
190
191
|
# File 'lib/bundler/rubygems_integration.rb', line 189
def ext_lock
EXT_LOCK
end
|
#fetch_all_remote_specs(remote) ⇒ Object
TODO: This is for older versions of Rubygems… should we support the X-Gemfile-Source header on these old versions? Maybe the newer implementation will work on older Rubygems? It seems difficult to keep this implementation and still send the header.
209
210
211
212
213
214
215
216
217
218
219
220
|
# File 'lib/bundler/rubygems_integration.rb', line 209
def fetch_all_remote_specs(remote)
old_sources = Bundler.rubygems.sources
Bundler.rubygems.sources = [remote.uri.to_s]
spec_list = fetch_specs(true, false)
fetch_prerelease_specs.each {|k, v| spec_list[k].push(*v) }
spec_list.values.first
ensure
Bundler.rubygems.sources = old_sources
end
|
#fetch_prerelease_specs ⇒ Object
199
200
201
202
203
|
# File 'lib/bundler/rubygems_integration.rb', line 199
def fetch_prerelease_specs
fetch_specs(false, true)
rescue Gem::RemoteFetcher::FetchError
{} end
|
#fetch_specs(all, pre, &blk) ⇒ Object
193
194
195
196
197
|
# File 'lib/bundler/rubygems_integration.rb', line 193
def fetch_specs(all, pre, &blk)
specs = Gem::SpecFetcher.new.list(all, pre)
specs.each { yield } if block_given?
specs
end
|
#gem_bindir ⇒ Object
123
124
125
|
# File 'lib/bundler/rubygems_integration.rb', line 123
def gem_bindir
Gem.bindir
end
|
#gem_cache ⇒ Object
135
136
137
|
# File 'lib/bundler/rubygems_integration.rb', line 135
def gem_cache
gem_path.map {|p| File.expand_path("cache", p) }
end
|
#gem_dir ⇒ Object
119
120
121
|
# File 'lib/bundler/rubygems_integration.rb', line 119
def gem_dir
Gem.dir
end
|
#gem_from_path(path, policy = nil) ⇒ Object
234
235
236
237
|
# File 'lib/bundler/rubygems_integration.rb', line 234
def gem_from_path(path, policy = nil)
require "rubygems/format"
Gem::Format.from_file_by_path(path, policy)
end
|
#gem_path ⇒ Object
131
132
133
|
# File 'lib/bundler/rubygems_integration.rb', line 131
def gem_path
Gem.path
end
|
#inflate(obj) ⇒ Object
102
103
104
|
# File 'lib/bundler/rubygems_integration.rb', line 102
def inflate(obj)
Gem.inflate(obj)
end
|
#load_path_insert_index ⇒ Object
38
39
40
|
# File 'lib/bundler/rubygems_integration.rb', line 38
def load_path_insert_index
Gem.load_path_insert_index
end
|
#loaded_gem_paths ⇒ Object
172
173
174
175
176
177
178
179
180
181
182
183
|
# File 'lib/bundler/rubygems_integration.rb', line 172
def loaded_gem_paths
if Gem::Specification.method_defined? :full_require_paths
loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
loaded_gem_paths.flatten
else
$LOAD_PATH.select do |p|
Bundler.rubygems.gem_path.any? {|gp| p =~ /^#{Regexp.escape(gp)}/ }
end
end
end
|
#loaded_specs(name) ⇒ Object
42
43
44
|
# File 'lib/bundler/rubygems_integration.rb', line 42
def loaded_specs(name)
Gem.loaded_specs[name]
end
|
#mark_loaded(spec) ⇒ Object
46
47
48
49
50
51
52
53
|
# File 'lib/bundler/rubygems_integration.rb', line 46
def mark_loaded(spec)
if spec.respond_to?(:activated=)
current = Gem.loaded_specs[spec.name]
current.activated = false if current
spec.activated = true
end
Gem.loaded_specs[spec.name] = spec
end
|
#marshal_spec_dir ⇒ Object
147
148
149
|
# File 'lib/bundler/rubygems_integration.rb', line 147
def marshal_spec_dir
Gem::MARSHAL_SPEC_DIR
end
|
#path(obj) ⇒ Object
74
75
76
|
# File 'lib/bundler/rubygems_integration.rb', line 74
def path(obj)
obj.to_s
end
|
78
79
80
|
# File 'lib/bundler/rubygems_integration.rb', line 78
def platforms
Gem.platforms
end
|
#preserve_paths ⇒ Object
167
168
169
170
|
# File 'lib/bundler/rubygems_integration.rb', line 167
def preserve_paths
yield
end
|
#provides?(req_str) ⇒ Boolean
26
27
28
|
# File 'lib/bundler/rubygems_integration.rb', line 26
def provides?(req_str)
self.class.provides?(req_str)
end
|
#read_binary(path) ⇒ Object
98
99
100
|
# File 'lib/bundler/rubygems_integration.rb', line 98
def read_binary(path)
Gem.read_binary(path)
end
|
#redefine_method(klass, method, &block) ⇒ Object
464
465
466
467
468
469
|
# File 'lib/bundler/rubygems_integration.rb', line 464
def redefine_method(klass, method, &block)
if klass.instance_methods(false).include?(method)
klass.send(:remove_method, method)
end
klass.send(:define_method, method, &block)
end
|
#replace_bin_path(specs) ⇒ Object
Used to make bin stubs that are not created by bundler work under bundler. The new Gem.bin_path only considers gems in specs
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
|
# File 'lib/bundler/rubygems_integration.rb', line 362
def replace_bin_path(specs)
gem_class = (class << Gem; self; end)
redefine_method(gem_class, :find_spec_for_exe) do |name, *args|
exec_name = args.first
spec = if exec_name
specs.find {|s| s.executables.include?(exec_name) }
else
specs.find {|s| s.name == name }
end
raise(Gem::Exception, "can't find executable #{exec_name}") unless spec
raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
unless spec.name == name
warn "Bundler is using a binstub that was created for a different gem.\n" \
"This is deprecated, in future versions you may need to `bundle binstub #{name}` " \
"to work around a system/bundle conflict."
end
spec
end
redefine_method(gem_class, :bin_path) do |name, *args|
exec_name = args.first
return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle"
spec = find_spec_for_exe(name, *args)
exec_name ||= spec.default_executable
gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
end
end
|
#replace_entrypoints(specs) ⇒ Object
Replace or hook into Rubygems to provide a bundlerized view of the world.
405
406
407
408
409
410
411
412
413
414
|
# File 'lib/bundler/rubygems_integration.rb', line 405
def replace_entrypoints(specs)
replace_gem(specs)
stub_rubygems(specs)
replace_bin_path(specs)
replace_refresh
Gem.clear_paths
end
|
#replace_gem(specs) ⇒ Object
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
|
# File 'lib/bundler/rubygems_integration.rb', line 296
def replace_gem(specs)
reverse_rubygems_kernel_mixin
executables = specs.map(&:executables).flatten
::Kernel.send(:define_method, :gem) do |dep, *reqs|
if executables.include? File.basename(caller.first.split(":").first)
break
end
reqs.pop if reqs.last.is_a?(Hash)
unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
dep = Gem::Dependency.new(dep, reqs)
end
spec = specs.find {|s| s.name == dep.name }
if spec.nil?
e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
e.name = dep.name
if e.respond_to?(:requirement=)
e.requirement = dep.requirement
else
e.version_requirement = dep.requirement
end
raise e
elsif dep !~ spec
e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
"Make sure all dependencies are added to Gemfile."
e.name = dep.name
if e.respond_to?(:requirement=)
e.requirement = dep.requirement
else
e.version_requirement = dep.requirement
end
raise e
end
true
end
end
|
#replace_refresh ⇒ Object
Because Bundler has a static view of what specs are available, we don’t #refresh, so stub it out.
398
399
400
401
|
# File 'lib/bundler/rubygems_integration.rb', line 398
def replace_refresh
gem_class = (class << Gem; self; end)
redefine_method(gem_class, :refresh) {}
end
|
#repository_subdirectories ⇒ Object
155
156
157
|
# File 'lib/bundler/rubygems_integration.rb', line 155
def repository_subdirectories
%w(cache doc gems specifications)
end
|
#reverse_rubygems_kernel_mixin ⇒ Object
284
285
286
287
288
289
290
291
292
293
294
|
# File 'lib/bundler/rubygems_integration.rb', line 284
def reverse_rubygems_kernel_mixin
::Kernel.class_eval do
if private_method_defined?(:gem_original_require)
alias_method :rubygems_require, :require
alias_method :require, :gem_original_require
end
undef gem
end
end
|
#ruby_engine ⇒ Object
94
95
96
|
# File 'lib/bundler/rubygems_integration.rb', line 94
def ruby_engine
Gem.ruby_engine
end
|
#security_policies ⇒ Object
275
276
277
278
279
280
281
282
|
# File 'lib/bundler/rubygems_integration.rb', line 275
def security_policies
@security_policies ||= begin
require "rubygems/security"
Gem::Security::Policies
rescue LoadError, NameError
{}
end
end
|
#security_policy_keys ⇒ Object
271
272
273
|
# File 'lib/bundler/rubygems_integration.rb', line 271
def security_policy_keys
%w(High Medium Low AlmostNo No).map {|level| "#{level}Security" }
end
|
#set_installed_by_version(spec, installed_by_version = Gem::VERSION) ⇒ Object
65
66
67
68
|
# File 'lib/bundler/rubygems_integration.rb', line 65
def set_installed_by_version(spec, installed_by_version = Gem::VERSION)
return unless spec.respond_to?(:installed_by_version=)
spec.installed_by_version = Gem::Version.create(installed_by_version)
end
|
#sources ⇒ Object
115
116
117
|
# File 'lib/bundler/rubygems_integration.rb', line 115
def sources
Gem.sources
end
|
#sources=(val) ⇒ Object
106
107
108
109
110
111
112
113
|
# File 'lib/bundler/rubygems_integration.rb', line 106
def sources=(val)
configuration
Gem.sources = val
end
|
#spec_cache_dirs ⇒ Object
139
140
141
142
143
144
145
|
# File 'lib/bundler/rubygems_integration.rb', line 139
def spec_cache_dirs
@spec_cache_dirs ||= begin
dirs = gem_path.map {|dir| File.join(dir, "specifications") }
dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) dirs.uniq.select {|dir| File.directory? dir }
end
end
|
#spec_from_gem(path, policy = nil) ⇒ Object
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
# File 'lib/bundler/rubygems_integration.rb', line 239
def spec_from_gem(path, policy = nil)
require "rubygems/security"
gem_from_path(path, security_policies[policy]).spec
rescue Gem::Package::FormatError
raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
rescue Exception, Gem::Exception, Gem::Security::Exception => e
if e.is_a?(Gem::Security::Exception) ||
e.message =~ /unknown trust policy|unsigned gem/i ||
e.message =~ /couldn't verify (meta)?data signature/i
raise SecurityError,
"The gem #{File.basename(path, ".gem")} can't be installed because " \
"the security policy didn't allow it, with the message: #{e.message}"
else
raise e
end
end
|
#spec_missing_extensions?(spec) ⇒ Boolean
70
71
72
|
# File 'lib/bundler/rubygems_integration.rb', line 70
def spec_missing_extensions?(spec)
!spec.respond_to?(:missing_extensions?) || spec.missing_extensions?
end
|
#stub_source_index(specs) ⇒ Object
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
# File 'lib/bundler/rubygems_integration.rb', line 339
def stub_source_index(specs)
Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
redefine_method(Gem::SourceIndex, :initialize) do |*args|
@gems = {}
Deprecate.skip_during do
self.spec_dirs = *args
add_specs(*specs)
end
end
end
|
#ui=(obj) ⇒ Object
185
186
187
|
# File 'lib/bundler/rubygems_integration.rb', line 185
def ui=(obj)
Gem::DefaultUserInteraction.ui = obj
end
|
#user_home ⇒ Object
127
128
129
|
# File 'lib/bundler/rubygems_integration.rb', line 127
def user_home
Gem.user_home
end
|
#validate(spec) ⇒ Object
55
56
57
58
59
60
61
62
63
|
# File 'lib/bundler/rubygems_integration.rb', line 55
def validate(spec)
Bundler.ui.silence { spec.validate(false) }
rescue Gem::InvalidSpecificationException => e
error_message = "The gemspec at #{spec.loaded_from} is not valid. Please fix this gemspec.\n" \
"The validation error was '#{e.message}'\n"
raise Gem::InvalidSpecificationException.new(error_message)
rescue Errno::ENOENT
nil
end
|
#version ⇒ Object
22
23
24
|
# File 'lib/bundler/rubygems_integration.rb', line 22
def version
self.class.version
end
|
#with_build_args(args) ⇒ Object
222
223
224
225
226
227
228
229
230
231
232
|
# File 'lib/bundler/rubygems_integration.rb', line 222
def with_build_args(args)
ext_lock.synchronize do
old_args = build_args
begin
self.build_args = args
yield
ensure
self.build_args = old_args
end
end
end
|