Class: Bundler::RubygemsIntegration

Inherits:
Object
  • Object
show all
Defined in:
lib/bundler/rubygems_integration.rb

Direct Known Subclasses

Legacy, Modern

Defined Under Namespace

Classes: AlmostModern, Ancient, Deprecate, Legacy, Modern, Transitional

Instance Method Summary collapse

Constructor Details

#initializeRubygemsIntegration

Returns a new instance of RubygemsIntegration.



3
4
5
6
# File 'lib/bundler/rubygems_integration.rb', line 3

def initialize
  # Work around a RubyGems bug
  configuration
end

Instance Method Details

#backport_segment_generationObject

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.



256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/bundler/rubygems_integration.rb', line 256

def backport_segment_generation
  Gem::Version.send(:define_method, :segments) do
    @segments_generated ||= false
    unless @segments_generated
      @segments ||= @version.scan(/[0-9a-z]+/i).map do |s|
        /^\d+$/ =~ s ? s.to_i : s
      end
    end
    @segments_generated = true
    @segments
  end
end

#bin_path(gem, bin, ver) ⇒ Object



72
73
74
# File 'lib/bundler/rubygems_integration.rb', line 72

def bin_path(gem, bin, ver)
  Gem.bin_path(gem, bin, ver)
end

#clear_pathsObject



68
69
70
# File 'lib/bundler/rubygems_integration.rb', line 68

def clear_paths
  Gem.clear_paths
end

#configurationObject



24
25
26
# File 'lib/bundler/rubygems_integration.rb', line 24

def configuration
  Gem.configuration
end

#download_gem(spec, uri, path) ⇒ Object



103
104
105
# File 'lib/bundler/rubygems_integration.rb', line 103

def download_gem(spec, uri, path)
  Gem::RemoteFetcher.fetcher.download(spec, uri, path)
end

#fetch_specs(all, pre, &blk) ⇒ Object



85
86
87
# File 'lib/bundler/rubygems_integration.rb', line 85

def fetch_specs(all, pre, &blk)
  Gem::SpecFetcher.new.list(all, pre).each(&blk)
end

#gem_bindirObject



52
53
54
# File 'lib/bundler/rubygems_integration.rb', line 52

def gem_bindir
  Gem.bindir
end

#gem_dirObject



48
49
50
# File 'lib/bundler/rubygems_integration.rb', line 48

def gem_dir
  Gem.dir
end

#gem_pathObject



60
61
62
# File 'lib/bundler/rubygems_integration.rb', line 60

def gem_path
  Gem.path
end

#inflate(obj) ⇒ Object



36
37
38
# File 'lib/bundler/rubygems_integration.rb', line 36

def inflate(obj)
  Gem.inflate(obj)
end

#loaded_specs(name) ⇒ Object



8
9
10
# File 'lib/bundler/rubygems_integration.rb', line 8

def loaded_specs(name)
  Gem.loaded_specs[name]
end

#mark_loaded(spec) ⇒ Object



12
13
14
# File 'lib/bundler/rubygems_integration.rb', line 12

def mark_loaded(spec)
  Gem.loaded_specs[spec.name] = spec
end

#marshal_spec_dirObject



64
65
66
# File 'lib/bundler/rubygems_integration.rb', line 64

def marshal_spec_dir
  Gem::MARSHAL_SPEC_DIR
end

#path(obj) ⇒ Object



16
17
18
# File 'lib/bundler/rubygems_integration.rb', line 16

def path(obj)
  obj.to_s
end

#platformsObject



20
21
22
# File 'lib/bundler/rubygems_integration.rb', line 20

def platforms
  Gem.platforms
end

#preserve_pathsObject



76
77
78
79
# File 'lib/bundler/rubygems_integration.rb', line 76

def preserve_paths
  # this is a no-op outside of Rubygems 1.8
  yield
end

#read_binary(path) ⇒ Object



32
33
34
# File 'lib/bundler/rubygems_integration.rb', line 32

def read_binary(path)
  Gem.read_binary(path)
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



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/bundler/rubygems_integration.rb', line 205

def replace_bin_path(specs)
  gem_class = (class << Gem ; self ; end)
  gem_class.send(:remove_method, :bin_path)
  gem_class.send(:define_method, :bin_path) do |name, *args|
    exec_name = args.first

    if exec_name == 'bundle'
      return ENV['BUNDLE_BIN_PATH']
    end

    spec = nil

    if exec_name
      spec = specs.find { |s| s.executables.include?(exec_name) }
      spec or raise Gem::Exception, "can't find executable #{exec_name}"
    else
      spec = specs.find  { |s| s.name == name }
      exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
    end

    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.



241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/bundler/rubygems_integration.rb', line 241

def replace_entrypoints(specs)
  reverse_rubygems_kernel_mixin

  replace_gem(specs)

  stub_rubygems(specs)

  replace_bin_path(specs)
  replace_refresh

  Gem.clear_paths
end

#replace_gem(specs) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/bundler/rubygems_integration.rb', line 119

def replace_gem(specs)
  executables = specs.map { |s| s.executables }.flatten

  ::Kernel.send(:define_method, :gem) do |dep, *reqs|
    if executables.include? File.basename(caller.first.split(':').first)
      return
    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_refreshObject

Because Bundler has a static view of what specs are available, we don’t #reflesh, so stub it out.



233
234
235
236
237
# File 'lib/bundler/rubygems_integration.rb', line 233

def replace_refresh
  gem_class = (class << Gem ; self ; end)
  gem_class.send(:remove_method, :refresh)
  gem_class.send(:define_method, :refresh) { }
end

#reverse_rubygems_kernel_mixinObject



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bundler/rubygems_integration.rb', line 107

def reverse_rubygems_kernel_mixin
  # Disable rubygems' gem activation system
  ::Kernel.class_eval do
    if private_method_defined?(:gem_original_require)
      alias rubygems_require require
      alias require gem_original_require
    end

    undef gem
  end
end

#ruby_engineObject



28
29
30
# File 'lib/bundler/rubygems_integration.rb', line 28

def ruby_engine
  Gem.ruby_engine
end

#sourcesObject



44
45
46
# File 'lib/bundler/rubygems_integration.rb', line 44

def sources
  Gem.sources
end

#sources=(val) ⇒ Object



40
41
42
# File 'lib/bundler/rubygems_integration.rb', line 40

def sources=(val)
  Gem.sources = val
end

#spec_from_gem(path) ⇒ Object



99
100
101
# File 'lib/bundler/rubygems_integration.rb', line 99

def spec_from_gem(path)
  Gem::Format.from_file_by_path(path).spec
end

#stub_source_index137(specs) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
# File 'lib/bundler/rubygems_integration.rb', line 170

def stub_source_index137(specs)
  # Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
  source_index_class = (class << Gem::SourceIndex ; self ; end)
  source_index_class.send(:remove_method, :from_gems_in)
  source_index_class.send(:define_method, :from_gems_in) do |*args|
    source_index = Gem::SourceIndex.new
    source_index.spec_dirs = *args
    source_index.add_specs(*specs)
    source_index
  end
end

#stub_source_index170(specs) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/bundler/rubygems_integration.rb', line 182

def stub_source_index170(specs)
  Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
  Gem::SourceIndex.send(:define_method, :initialize) do |*args|
    @gems = {}
    # You're looking at this thinking: Oh! This is how I make those
    # rubygems deprecations go away!
    #
    # You'd be correct BUT using of this method in production code
    # must be approved by the rubygems team itself!
    #
    # This is your warning. If you use this and don't have approval
    # we can't protect you.
    #
    Deprecate.skip_during do
      self.spec_dirs = *args
      add_specs(*specs)
    end
  end
end

#ui=(obj) ⇒ Object



81
82
83
# File 'lib/bundler/rubygems_integration.rb', line 81

def ui=(obj)
  Gem::DefaultUserInteraction.ui = obj
end

#user_homeObject



56
57
58
# File 'lib/bundler/rubygems_integration.rb', line 56

def user_home
  Gem.user_home
end

#with_build_args(args) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/bundler/rubygems_integration.rb', line 89

def with_build_args(args)
  old_args = Gem::Command.build_args
  begin
    Gem::Command.build_args = args
    yield
  ensure
    Gem::Command.build_args = old_args
  end
end