1# -*- ruby -*-
2#--
3# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4# All rights reserved.
5# See LICENSE.txt for permissions.
6#++
7
8require 'rbconfig'
9
10module Gem
11  VERSION = '2.0.14'
12end
13
14# Must be first since it unloads the prelude from 1.9.2
15require 'rubygems/compatibility'
16
17require 'rubygems/defaults'
18require 'rubygems/deprecate'
19require 'rubygems/errors'
20
21##
22# RubyGems is the Ruby standard for publishing and managing third party
23# libraries.
24#
25# For user documentation, see:
26#
27# * <tt>gem help</tt> and <tt>gem help [command]</tt>
28# * {RubyGems User Guide}[http://docs.rubygems.org/read/book/1]
29# * {Frequently Asked Questions}[http://docs.rubygems.org/read/book/3]
30#
31# For gem developer documentation see:
32#
33# * {Creating Gems}[http://docs.rubygems.org/read/chapter/5]
34# * Gem::Specification
35# * Gem::Version for version dependency notes
36#
37# Further RubyGems documentation can be found at:
38#
39# * {RubyGems Guides}[http://guides.rubygems.org]
40# * {RubyGems API}[http://rubygems.rubyforge.org/rdoc] (also available from
41#   <tt>gem server</tt>)
42#
43# == RubyGems Plugins
44#
45# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
46# $LOAD_PATH.  Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
47# placed at the root of your gem's #require_path.  Plugins are discovered via
48# Gem::find_files then loaded.  Take care when implementing a plugin as your
49# plugin file may be loaded multiple times if multiple versions of your gem
50# are installed.
51#
52# For an example plugin, see the graph gem which adds a `gem graph` command.
53#
54# == RubyGems Defaults, Packaging
55#
56# RubyGems defaults are stored in rubygems/defaults.rb.  If you're packaging
57# RubyGems or implementing Ruby you can change RubyGems' defaults.
58#
59# For RubyGems packagers, provide lib/rubygems/operating_system.rb and
60# override any defaults from lib/rubygems/defaults.rb.
61#
62# For Ruby implementers, provide lib/rubygems/defaults/#{RUBY_ENGINE}.rb and
63# override any defaults from lib/rubygems/defaults.rb.
64#
65# If you need RubyGems to perform extra work on install or uninstall, your
66# defaults override file can set pre and post install and uninstall hooks.
67# See Gem::pre_install, Gem::pre_uninstall, Gem::post_install,
68# Gem::post_uninstall.
69#
70# == Bugs
71#
72# You can submit bugs to the
73# {RubyGems bug tracker}[https://github.com/rubygems/rubygems/issues]
74# on GitHub
75#
76# == Credits
77#
78# RubyGems is currently maintained by Eric Hodel.
79#
80# RubyGems was originally developed at RubyConf 2003 by:
81#
82# * Rich Kilmer  -- rich(at)infoether.com
83# * Chad Fowler  -- chad(at)chadfowler.com
84# * David Black  -- dblack(at)wobblini.net
85# * Paul Brannan -- paul(at)atdesk.com
86# * Jim Weirch   -- jim(at)weirichhouse.org
87#
88# Contributors:
89#
90# * Gavin Sinclair     -- gsinclair(at)soyabean.com.au
91# * George Marrows     -- george.marrows(at)ntlworld.com
92# * Dick Davies        -- rasputnik(at)hellooperator.net
93# * Mauricio Fernandez -- batsman.geo(at)yahoo.com
94# * Simon Strandgaard  -- neoneye(at)adslhome.dk
95# * Dave Glasser       -- glasser(at)mit.edu
96# * Paul Duncan        -- pabs(at)pablotron.org
97# * Ville Aine         -- vaine(at)cs.helsinki.fi
98# * Eric Hodel         -- drbrain(at)segment7.net
99# * Daniel Berger      -- djberg96(at)gmail.com
100# * Phil Hagelberg     -- technomancy(at)gmail.com
101# * Ryan Davis         -- ryand-ruby(at)zenspider.com
102# * Evan Phoenix       -- evan(at)fallingsnow.net
103# * Steve Klabnik      -- steve(at)steveklabnik.com
104#
105# (If your name is missing, PLEASE let us know!)
106#
107# See {LICENSE.txt}[rdoc-ref:lib/rubygems/LICENSE.txt] for permissions.
108#
109# Thanks!
110#
111# -The RubyGems Team
112
113
114module Gem
115  RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__)
116
117  ##
118  # An Array of Regexps that match windows ruby platforms.
119
120  WIN_PATTERNS = [
121    /bccwin/i,
122    /cygwin/i,
123    /djgpp/i,
124    /mingw/i,
125    /mswin/i,
126    /wince/i,
127  ]
128
129  GEM_DEP_FILES = %w[
130    gem.deps.rb
131    Gemfile
132    Isolate
133  ]
134
135  ##
136  # Subdirectories in a gem repository
137
138  REPOSITORY_SUBDIRECTORIES = %w[
139    build_info
140    cache
141    doc
142    gems
143    specifications
144  ]
145
146  @@win_platform = nil
147
148  @configuration = nil
149  @loaded_specs = {}
150  @path_to_default_spec_map = {}
151  @platforms = []
152  @ruby = nil
153  @sources = nil
154
155  @post_build_hooks     ||= []
156  @post_install_hooks   ||= []
157  @post_uninstall_hooks ||= []
158  @pre_uninstall_hooks  ||= []
159  @pre_install_hooks    ||= []
160  @pre_reset_hooks      ||= []
161  @post_reset_hooks     ||= []
162
163  ##
164  # Try to activate a gem containing +path+. Returns true if
165  # activation succeeded or wasn't needed because it was already
166  # activated. Returns false if it can't find the path in a gem.
167
168  def self.try_activate path
169    # finds the _latest_ version... regardless of loaded specs and their deps
170    # if another gem had a requirement that would mean we shouldn't
171    # activate the latest version, then either it would alreaby be activated
172    # or if it was ambigious (and thus unresolved) the code in our custom
173    # require will try to activate the more specific version.
174
175    spec = Gem::Specification.find_inactive_by_path path
176
177    unless spec
178      spec = Gem::Specification.find_by_path path
179      return true if spec && spec.activated?
180      return false
181    end
182
183    begin
184      spec.activate
185    rescue Gem::LoadError # this could fail due to gem dep collisions, go lax
186      Gem::Specification.find_by_name(spec.name).activate
187    end
188
189    return true
190  end
191
192  def self.needs
193    rs = Gem::RequestSet.new
194
195    yield rs
196
197    finish_resolve rs
198  end
199
200  def self.finish_resolve(request_set=Gem::RequestSet.new)
201    request_set.import Gem::Specification.unresolved_deps.values
202
203    request_set.resolve_current.each do |s|
204      s.full_spec.activate
205    end
206  end
207
208  def self.detect_gemdeps
209    if path = ENV['RUBYGEMS_GEMDEPS']
210      path = path.dup.untaint
211
212      if path == "-"
213        here = Dir.pwd.untaint
214        start = here
215
216        begin
217          while true
218            path = GEM_DEP_FILES.find { |f| File.file?(f) }
219
220            if path
221              path = File.join here, path
222              break
223            end
224
225            Dir.chdir ".."
226
227            # If we're at a toplevel, stop.
228            return if Dir.pwd == here
229
230            here = Dir.pwd
231          end
232        ensure
233          Dir.chdir start
234        end
235      end
236
237      path.untaint
238
239      return unless File.file? path
240
241      rs = Gem::RequestSet.new
242      rs.load_gemdeps path
243
244      rs.resolve_current.map do |s|
245        sp = s.full_spec
246        sp.activate
247        sp
248      end
249    end
250  end
251
252  ##
253  # Find the full path to the executable for gem +name+.  If the +exec_name+
254  # is not given, the gem's default_executable is chosen, otherwise the
255  # specified executable's path is returned.  +requirements+ allows
256  # you to specify specific gem versions.
257
258  def self.bin_path(name, exec_name = nil, *requirements)
259    # TODO: fails test_self_bin_path_bin_file_gone_in_latest
260    # Gem::Specification.find_by_name(name, *requirements).bin_file exec_name
261
262    raise ArgumentError, "you must supply exec_name" unless exec_name
263
264    requirements = Gem::Requirement.default if
265      requirements.empty?
266
267    specs = Gem::Dependency.new(name, requirements).matching_specs(true)
268
269    raise Gem::GemNotFoundException,
270          "can't find gem #{name} (#{requirements})" if specs.empty?
271
272    specs = specs.find_all { |spec|
273      spec.executables.include? exec_name
274    } if exec_name
275
276    unless spec = specs.last
277      msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
278      raise Gem::GemNotFoundException, msg
279    end
280
281    spec.bin_file exec_name
282  end
283
284  ##
285  # The mode needed to read a file as straight binary.
286
287  def self.binary_mode
288    'rb'
289  end
290
291  ##
292  # The path where gem executables are to be installed.
293
294  def self.bindir(install_dir=Gem.dir)
295    # TODO: move to Gem::Dirs
296    return File.join install_dir, 'bin' unless
297      install_dir.to_s == Gem.default_dir.to_s
298    Gem.default_bindir
299  end
300
301  ##
302  # Reset the +dir+ and +path+ values.  The next time +dir+ or +path+
303  # is requested, the values will be calculated from scratch.  This is
304  # mainly used by the unit tests to provide test isolation.
305
306  def self.clear_paths
307    @paths         = nil
308    @user_home     = nil
309    Gem::Specification.reset
310    Gem::Security.reset if defined?(Gem::Security)
311  end
312
313  ##
314  # The path to standard location of the user's .gemrc file.
315
316  def self.config_file
317    @config_file ||= File.join Gem.user_home, '.gemrc'
318  end
319
320  ##
321  # The standard configuration object for gems.
322
323  def self.configuration
324    @configuration ||= Gem::ConfigFile.new []
325  end
326
327  ##
328  # Use the given configuration object (which implements the ConfigFile
329  # protocol) as the standard configuration object.
330
331  def self.configuration=(config)
332    @configuration = config
333  end
334
335  ##
336  # The path the the data directory specified by the gem name.  If the
337  # package is not available as a gem, return nil.
338
339  def self.datadir(gem_name)
340# TODO: deprecate and move to Gem::Specification
341#       and drop the extra ", gem_name" which is uselessly redundant
342    spec = @loaded_specs[gem_name]
343    return nil if spec.nil?
344    File.join spec.full_gem_path, "data", gem_name
345  end
346
347  ##
348  # A Zlib::Deflate.deflate wrapper
349
350  def self.deflate(data)
351    require 'zlib'
352    Zlib::Deflate.deflate data
353  end
354
355  # DOC: needs doc'd or :nodoc'd
356  def self.paths
357    @paths ||= Gem::PathSupport.new
358  end
359
360  # DOC: needs doc'd or :nodoc'd
361  def self.paths=(env)
362    clear_paths
363    @paths = Gem::PathSupport.new env
364    Gem::Specification.dirs = @paths.path # FIX: home is at end
365  end
366
367  ##
368  # The path where gems are to be installed.
369  #--
370  # FIXME deprecate these once everything else has been done -ebh
371
372  def self.dir
373    # TODO: raise "no"
374    paths.home
375  end
376
377  def self.path
378    # TODO: raise "no"
379    paths.path
380  end
381
382  ##
383  # Quietly ensure the Gem directory +dir+ contains all the proper
384  # subdirectories.  If we can't create a directory due to a permission
385  # problem, then we will silently continue.
386  #
387  # If +mode+ is given, missing directories are created with this mode.
388  #
389  # World-writable directories will never be created.
390
391  def self.ensure_gem_subdirectories dir = Gem.dir, mode = nil
392    old_umask = File.umask
393    File.umask old_umask | 002
394
395    require 'fileutils'
396
397    options = {}
398
399    options[:mode] = mode if mode
400
401    REPOSITORY_SUBDIRECTORIES.each do |name|
402      subdir = File.join dir, name
403      next if File.exist? subdir
404      FileUtils.mkdir_p subdir, options rescue nil
405    end
406  ensure
407    File.umask old_umask
408  end
409
410  ##
411  # Returns a list of paths matching +glob+ that can be used by a gem to pick
412  # up features from other gems.  For example:
413  #
414  #   Gem.find_files('rdoc/discover').each do |path| load path end
415  #
416  # if +check_load_path+ is true (the default), then find_files also searches
417  # $LOAD_PATH for files as well as gems.
418  #
419  # Note that find_files will return all files even if they are from different
420  # versions of the same gem.
421
422  def self.find_files(glob, check_load_path=true)
423    files = []
424
425    if check_load_path
426      files = $LOAD_PATH.map { |load_path|
427        Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"]
428      }.flatten.select { |file| File.file? file.untaint }
429    end
430
431    files.concat Gem::Specification.map { |spec|
432      spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
433    }.flatten
434
435    # $LOAD_PATH might contain duplicate entries or reference
436    # the spec dirs directly, so we prune.
437    files.uniq! if check_load_path
438
439    return files
440  end
441
442  ##
443  # Finds the user's home directory.
444  #--
445  # Some comments from the ruby-talk list regarding finding the home
446  # directory:
447  #
448  #   I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
449  #   to be depending on HOME in those code samples. I propose that
450  #   it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
451  #   least on Win32).
452  #++
453  #--
454  #
455  # FIXME move to pathsupport
456  #
457  #++
458
459  def self.find_home
460    windows = File::ALT_SEPARATOR
461    if not windows or RUBY_VERSION >= '1.9' then
462      File.expand_path "~"
463    else
464      ['HOME', 'USERPROFILE'].each do |key|
465        return File.expand_path ENV[key] if ENV[key]
466      end
467
468      if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
469        File.expand_path "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
470      end
471    end
472  rescue
473    if windows then
474      File.expand_path File.join(ENV['HOMEDRIVE'] || ENV['SystemDrive'], '/')
475    else
476      File.expand_path "/"
477    end
478  end
479
480  private_class_method :find_home
481
482  ##
483  # Zlib::GzipReader wrapper that unzips +data+.
484
485  def self.gunzip(data)
486    # TODO: move to utils
487    require 'stringio'
488    require 'zlib'
489    data = StringIO.new data
490
491    unzipped = Zlib::GzipReader.new(data).read
492    unzipped.force_encoding Encoding::BINARY if Object.const_defined? :Encoding
493    unzipped
494  end
495
496  ##
497  # Zlib::GzipWriter wrapper that zips +data+.
498
499  def self.gzip(data)
500    # TODO: move to utils
501    require 'stringio'
502    require 'zlib'
503    zipped = StringIO.new
504    zipped.set_encoding Encoding::BINARY if Object.const_defined? :Encoding
505
506    Zlib::GzipWriter.wrap zipped do |io| io.write data end
507
508    zipped.string
509  end
510
511  ##
512  # A Zlib::Inflate#inflate wrapper
513
514  def self.inflate(data)
515    # TODO: move to utils
516    require 'zlib'
517    Zlib::Inflate.inflate data
518  end
519
520  ##
521  # Top level install helper method. Allows you to install gems interactively:
522  #
523  #   % irb
524  #   >> Gem.install "minitest"
525  #   Fetching: minitest-3.0.1.gem (100%)
526  #   => [#<Gem::Specification:0x1013b4528 @name="minitest", ...>]
527
528  def self.install name, version = Gem::Requirement.default
529    require "rubygems/dependency_installer"
530    inst = Gem::DependencyInstaller.new
531    inst.install name, version
532    inst.installed_gems
533  end
534
535  ##
536  # Get the default RubyGems API host. This is normally
537  # <tt>https://rubygems.org</tt>.
538
539  def self.host
540    # TODO: move to utils
541    @host ||= Gem::DEFAULT_HOST
542  end
543
544  ## Set the default RubyGems API host.
545
546  def self.host= host
547    # TODO: move to utils
548    @host = host
549  end
550
551  ##
552  # The index to insert activated gem paths into the $LOAD_PATH.
553  #
554  # Defaults to the site lib directory unless gem_prelude.rb has loaded paths,
555  # then it inserts the activated gem's paths before the gem_prelude.rb paths
556  # so you can override the gem_prelude.rb default $LOAD_PATH paths.
557
558  def self.load_path_insert_index
559    index = $LOAD_PATH.index ConfigMap[:sitelibdir]
560
561    index
562  end
563
564  @yaml_loaded = false
565
566  ##
567  # Loads YAML, preferring Psych
568
569  def self.load_yaml
570    return if @yaml_loaded
571    return unless defined?(gem)
572
573    test_syck = ENV['TEST_SYCK']
574
575    unless test_syck
576      begin
577        gem 'psych', '~> 1.2', '>= 1.2.1'
578      rescue Gem::LoadError
579        # It's OK if the user does not have the psych gem installed.  We will
580        # attempt to require the stdlib version
581      end
582
583      begin
584        # Try requiring the gem version *or* stdlib version of psych.
585        require 'psych'
586      rescue ::LoadError
587        # If we can't load psych, thats fine, go on.
588      else
589        # If 'yaml' has already been required, then we have to
590        # be sure to switch it over to the newly loaded psych.
591        if defined?(YAML::ENGINE) && YAML::ENGINE.yamler != "psych"
592          YAML::ENGINE.yamler = "psych"
593        end
594
595        require 'rubygems/psych_additions'
596        require 'rubygems/psych_tree'
597      end
598    end
599
600    require 'yaml'
601
602    # If we're supposed to be using syck, then we may have to force
603    # activate it via the YAML::ENGINE API.
604    if test_syck and defined?(YAML::ENGINE)
605      YAML::ENGINE.yamler = "syck" unless YAML::ENGINE.syck?
606    end
607
608    # Now that we're sure some kind of yaml library is loaded, pull
609    # in our hack to deal with Syck's DefaultKey ugliness.
610    require 'rubygems/syck_hack'
611
612    @yaml_loaded = true
613  end
614
615  ##
616  # The file name and line number of the caller of the caller of this method.
617
618  def self.location_of_caller
619    caller[1] =~ /(.*?):(\d+).*?$/i
620    file = $1
621    lineno = $2.to_i
622
623    # TODO: it is ALWAYS joined! STUPID!
624    [file, lineno]
625  end
626
627  ##
628  # The version of the Marshal format for your Ruby.
629
630  def self.marshal_version
631    "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
632  end
633
634  ##
635  # Set array of platforms this RubyGems supports (primarily for testing).
636
637  def self.platforms=(platforms)
638    @platforms = platforms
639  end
640
641  ##
642  # Array of platforms this RubyGems supports.
643
644  def self.platforms
645    @platforms ||= []
646    if @platforms.empty?
647      @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
648    end
649    @platforms
650  end
651
652  ##
653  # Adds a post-build hook that will be passed an Gem::Installer instance
654  # when Gem::Installer#install is called.  The hook is called after the gem
655  # has been extracted and extensions have been built but before the
656  # executables or gemspec has been written.  If the hook returns +false+ then
657  # the gem's files will be removed and the install will be aborted.
658
659  def self.post_build(&hook)
660    @post_build_hooks << hook
661  end
662
663  ##
664  # Adds a post-install hook that will be passed an Gem::Installer instance
665  # when Gem::Installer#install is called
666
667  def self.post_install(&hook)
668    @post_install_hooks << hook
669  end
670
671  ##
672  # Adds a post-installs hook that will be passed a Gem::DependencyInstaller
673  # and a list of installed specifications when
674  # Gem::DependencyInstaller#install is complete
675
676  def self.done_installing(&hook)
677    @done_installing_hooks << hook
678  end
679
680  ##
681  # Adds a hook that will get run after Gem::Specification.reset is
682  # run.
683
684  def self.post_reset(&hook)
685    @post_reset_hooks << hook
686  end
687
688  ##
689  # Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance
690  # and the spec that was uninstalled when Gem::Uninstaller#uninstall is
691  # called
692
693  def self.post_uninstall(&hook)
694    @post_uninstall_hooks << hook
695  end
696
697  ##
698  # Adds a pre-install hook that will be passed an Gem::Installer instance
699  # when Gem::Installer#install is called.  If the hook returns +false+ then
700  # the install will be aborted.
701
702  def self.pre_install(&hook)
703    @pre_install_hooks << hook
704  end
705
706  ##
707  # Adds a hook that will get run before Gem::Specification.reset is
708  # run.
709
710  def self.pre_reset(&hook)
711    @pre_reset_hooks << hook
712  end
713
714  ##
715  # Adds a pre-uninstall hook that will be passed an Gem::Uninstaller instance
716  # and the spec that will be uninstalled when Gem::Uninstaller#uninstall is
717  # called
718
719  def self.pre_uninstall(&hook)
720    @pre_uninstall_hooks << hook
721  end
722
723  ##
724  # The directory prefix this RubyGems was installed at. If your
725  # prefix is in a standard location (ie, rubygems is installed where
726  # you'd expect it to be), then prefix returns nil.
727
728  def self.prefix
729    prefix = File.dirname RUBYGEMS_DIR
730
731    if prefix != File.expand_path(ConfigMap[:sitelibdir]) and
732       prefix != File.expand_path(ConfigMap[:libdir]) and
733       'lib' == File.basename(RUBYGEMS_DIR) then
734      prefix
735    end
736  end
737
738  ##
739  # Refresh available gems from disk.
740
741  def self.refresh
742    Gem::Specification.reset
743  end
744
745  ##
746  # Safely read a file in binary mode on all platforms.
747
748  def self.read_binary(path)
749    File.open path, binary_mode do |f| f.read end
750  end
751
752  ##
753  # The path to the running Ruby interpreter.
754
755  def self.ruby
756    if @ruby.nil? then
757      @ruby = File.join(ConfigMap[:bindir],
758                        "#{ConfigMap[:ruby_install_name]}#{ConfigMap[:EXEEXT]}")
759
760      @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
761    end
762
763    @ruby
764  end
765
766  ##
767  # Returns the latest release-version specification for the gem +name+.
768
769  def self.latest_spec_for name
770    dependency   = Gem::Dependency.new name
771    fetcher      = Gem::SpecFetcher.fetcher
772    spec_tuples, = fetcher.spec_for_dependency dependency
773
774    spec, = spec_tuples.first
775
776    spec
777  end
778
779  ##
780  # Returns the latest release version of RubyGems.
781
782  def self.latest_rubygems_version
783    latest_version_for('rubygems-update') or
784      raise "Can't find 'rubygems-update' in any repo. Check `gem source list`."
785  end
786
787  ##
788  # Returns the version of the latest release-version of gem +name+
789
790  def self.latest_version_for name
791    spec = latest_spec_for name
792    spec and spec.version
793  end
794
795  ##
796  # A Gem::Version for the currently running ruby.
797
798  def self.ruby_version
799    return @ruby_version if defined? @ruby_version
800    version = RUBY_VERSION.dup
801
802    if defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL != -1 then
803      version << ".#{RUBY_PATCHLEVEL}"
804    elsif defined?(RUBY_REVISION) then
805      version << ".dev.#{RUBY_REVISION}"
806    end
807
808    @ruby_version = Gem::Version.new version
809  end
810
811  ##
812  # A Gem::Version for the currently running RubyGems
813
814  def self.rubygems_version
815    return @rubygems_version if defined? @rubygems_version
816    @rubygems_version = Gem::Version.new Gem::VERSION
817  end
818
819  ##
820  # Returns an Array of sources to fetch remote gems from. Uses
821  # default_sources if the sources list is empty.
822
823  def self.sources
824    @sources ||= Gem::SourceList.from(default_sources)
825  end
826
827  ##
828  # Need to be able to set the sources without calling
829  # Gem.sources.replace since that would cause an infinite loop.
830  #
831  # DOC: This comment is not documentation about the method itself, it's
832  # more of a code comment about the implementation.
833
834  def self.sources= new_sources
835    if !new_sources
836      @sources = nil
837    else
838      @sources = Gem::SourceList.from(new_sources)
839    end
840  end
841
842  ##
843  # Glob pattern for require-able path suffixes.
844
845  def self.suffix_pattern
846    @suffix_pattern ||= "{#{suffixes.join(',')}}"
847  end
848
849  ##
850  # Suffixes for require-able paths.
851
852  def self.suffixes
853    @suffixes ||= ['',
854                   '.rb',
855                   *%w(DLEXT DLEXT2).map { |key|
856                     val = RbConfig::CONFIG[key]
857                     next unless val and not val.empty?
858                     ".#{val}"
859                   }
860                  ].compact.uniq
861  end
862
863  ##
864  # Prints the amount of time the supplied block takes to run using the debug
865  # UI output.
866
867  def self.time(msg, width = 0, display = Gem.configuration.verbose)
868    now = Time.now
869
870    value = yield
871
872    elapsed = Time.now - now
873
874    ui.say "%2$*1$s: %3$3.3fs" % [-width, msg, elapsed] if display
875
876    value
877  end
878
879  ##
880  # Lazily loads DefaultUserInteraction and returns the default UI.
881
882  def self.ui
883    require 'rubygems/user_interaction'
884
885    Gem::DefaultUserInteraction.ui
886  end
887
888  ##
889  # Use the +home+ and +paths+ values for Gem.dir and Gem.path.  Used mainly
890  # by the unit tests to provide environment isolation.
891
892  def self.use_paths(home, *paths)
893    paths = nil if paths == [nil]
894    paths = paths.first if Array === Array(paths).first
895    self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
896    # TODO: self.paths = home, paths
897  end
898
899  ##
900  # The home directory for the user.
901
902  def self.user_home
903    @user_home ||= find_home.untaint
904  end
905
906  ##
907  # Is this a windows platform?
908
909  def self.win_platform?
910    if @@win_platform.nil? then
911      ruby_platform = RbConfig::CONFIG['host_os']
912      @@win_platform = !!WIN_PATTERNS.find { |r| ruby_platform =~ r }
913    end
914
915    @@win_platform
916  end
917
918  ##
919  # Load +plugins+ as ruby files
920
921  def self.load_plugin_files(plugins)
922    plugins.each do |plugin|
923
924      # Skip older versions of the GemCutter plugin: Its commands are in
925      # RubyGems proper now.
926
927      next if plugin =~ /gemcutter-0\.[0-3]/
928
929      begin
930        load plugin
931      rescue ::Exception => e
932        details = "#{plugin.inspect}: #{e.message} (#{e.class})"
933        warn "Error loading RubyGems plugin #{details}"
934      end
935    end
936  end
937
938  ##
939  # Find all 'rubygems_plugin' files in installed gems and load them
940
941  def self.load_plugins
942    load_plugin_files find_files('rubygems_plugin', false)
943  end
944
945  ##
946  # Find all 'rubygems_plugin' files in $LOAD_PATH and load them
947
948  def self.load_env_plugins
949    path = "rubygems_plugin"
950
951    files = []
952    $LOAD_PATH.each do |load_path|
953      globbed = Dir["#{File.expand_path path, load_path}#{Gem.suffix_pattern}"]
954
955      globbed.each do |load_path_file|
956        files << load_path_file if File.file?(load_path_file.untaint)
957      end
958    end
959
960    load_plugin_files files
961  end
962
963  # FIX: Almost everywhere else we use the `def self.` way of defining class
964  # methods, and then we switch over to `class << self` here. Pick one or the
965  # other.
966  class << self
967
968    ##
969    # Hash of loaded Gem::Specification keyed by name
970
971    attr_reader :loaded_specs
972
973    ##
974    # Register a Gem::Specification for default gem
975
976    def register_default_spec(spec)
977      spec.files.each do |file|
978        @path_to_default_spec_map[file] = spec
979      end
980    end
981
982    ##
983    # Find a Gem::Specification of default gem from +path+
984
985    def find_unresolved_default_spec(path)
986      Gem.suffixes.each do |suffix|
987        spec = @path_to_default_spec_map["#{path}#{suffix}"]
988        return spec if spec
989      end
990      nil
991    end
992
993    ##
994    # Remove needless Gem::Specification of default gem from
995    # unresolved default gem list
996
997    def remove_unresolved_default_spec(spec)
998      spec.files.each do |file|
999        @path_to_default_spec_map.delete(file)
1000      end
1001    end
1002
1003    ##
1004    # Clear default gem related varibles. It is for test
1005
1006    def clear_default_specs
1007      @path_to_default_spec_map.clear
1008    end
1009
1010    ##
1011    # The list of hooks to be run after Gem::Installer#install extracts files
1012    # and builds extensions
1013
1014    attr_reader :post_build_hooks
1015
1016    ##
1017    # The list of hooks to be run after Gem::Installer#install completes
1018    # installation
1019
1020    attr_reader :post_install_hooks
1021
1022    ##
1023    # The list of hooks to be run after Gem::DependencyInstaller installs a
1024    # set of gems
1025
1026    attr_reader :done_installing_hooks
1027
1028    ##
1029    # The list of hooks to be run after Gem::Specification.reset is run.
1030
1031    attr_reader :post_reset_hooks
1032
1033    ##
1034    # The list of hooks to be run after Gem::Uninstaller#uninstall completes
1035    # installation
1036
1037    attr_reader :post_uninstall_hooks
1038
1039    ##
1040    # The list of hooks to be run before Gem::Installer#install does any work
1041
1042    attr_reader :pre_install_hooks
1043
1044    ##
1045    # The list of hooks to be run before Gem::Specification.reset is run.
1046
1047    attr_reader :pre_reset_hooks
1048
1049    ##
1050    # The list of hooks to be run before Gem::Uninstaller#uninstall does any
1051    # work
1052
1053    attr_reader :pre_uninstall_hooks
1054  end
1055
1056  ##
1057  # Location of Marshal quick gemspecs on remote repositories
1058
1059  MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
1060
1061  autoload :ConfigFile,         'rubygems/config_file'
1062  autoload :Dependency,         'rubygems/dependency'
1063  autoload :DependencyList,     'rubygems/dependency_list'
1064  autoload :DependencyResolver, 'rubygems/dependency_resolver'
1065  autoload :PathSupport,        'rubygems/path_support'
1066  autoload :Platform,           'rubygems/platform'
1067  autoload :RequestSet,         'rubygems/request_set'
1068  autoload :Requirement,        'rubygems/requirement'
1069  autoload :SourceList,         'rubygems/source_list'
1070  autoload :SpecFetcher,        'rubygems/spec_fetcher'
1071  autoload :Specification,      'rubygems/specification'
1072  autoload :Version,            'rubygems/version'
1073  autoload :Source,             'rubygems/source'
1074
1075  require "rubygems/specification"
1076end
1077
1078require 'rubygems/exceptions'
1079
1080# REFACTOR: This should be pulled out into some kind of hacks file.
1081gem_preluded = Gem::GEM_PRELUDE_SUCKAGE and defined? Gem
1082unless gem_preluded then # TODO: remove guard after 1.9.2 dropped
1083  begin
1084    ##
1085    # Defaults the operating system (or packager) wants to provide for RubyGems.
1086
1087    require 'rubygems/defaults/operating_system'
1088  rescue LoadError
1089  end
1090
1091  if defined?(RUBY_ENGINE) then
1092    begin
1093      ##
1094      # Defaults the ruby implementation wants to provide for RubyGems
1095
1096      require "rubygems/defaults/#{RUBY_ENGINE}"
1097    rescue LoadError
1098    end
1099  end
1100end
1101
1102##
1103# Loads the default specs.
1104Gem::Specification.load_defaults
1105
1106require 'rubygems/core_ext/kernel_gem'
1107require 'rubygems/core_ext/kernel_require'
1108
1109Gem.detect_gemdeps
1110