1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 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 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 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 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 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 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
|
# -*- ruby -*-
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'rubygems/defaults'
require 'thread'
require 'etc'
##
# RubyGems is the Ruby standard for publishing and managing third party
# libraries.
#
# For user documentation, see:
#
# * <tt>gem help</tt> and <tt>gem help [command]</tt>
# * {RubyGems User Guide}[http://docs.rubygems.org/read/book/1]
# * {Frequently Asked Questions}[http://docs.rubygems.org/read/book/3]
#
# For gem developer documentation see:
#
# * {Creating Gems}[http://docs.rubygems.org/read/chapter/5]
# * Gem::Specification
# * Gem::Version for version dependency notes
#
# Further RubyGems documentation can be found at:
#
# * {RubyGems API}[http://rubygems.rubyforge.org/rdoc] (also available from
# <tt>gem server</tt>)
# * {RubyGems Bookshelf}[http://rubygem.org]
#
# == RubyGems Plugins
#
# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
# placed at the root of your gem's #require_path. Plugins are discovered via
# Gem::find_files then loaded. Take care when implementing a plugin as your
# plugin file may be loaded multiple times if multiple versions of your gem
# are installed.
#
# For an example plugin, see the graph gem which adds a `gem graph` command.
#
# == RubyGems Defaults, Packaging
#
# RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging
# RubyGems or implementing Ruby you can change RubyGems' defaults.
#
# For RubyGems packagers, provide lib/rubygems/operating_system.rb and
# override any defaults from lib/rubygems/defaults.rb.
#
# For Ruby implementers, provide lib/rubygems/#{RUBY_ENGINE}.rb and override
# any defaults from lib/rubygems/defaults.rb.
#
# If you need RubyGems to perform extra work on install or uninstall, your
# defaults override file can set pre and post install and uninstall hooks.
# See Gem::pre_install, Gem::pre_uninstall, Gem::post_install,
# Gem::post_uninstall.
#
# == Bugs
#
# You can submit bugs to the
# {RubyGems bug tracker}[http://rubyforge.org/tracker/?atid=575&group_id=126]
# on RubyForge
#
# == Credits
#
# RubyGems is currently maintained by Eric Hodel.
#
# RubyGems was originally developed at RubyConf 2003 by:
#
# * Rich Kilmer -- rich(at)infoether.com
# * Chad Fowler -- chad(at)chadfowler.com
# * David Black -- dblack(at)wobblini.net
# * Paul Brannan -- paul(at)atdesk.com
# * Jim Weirch -- jim(at)weirichhouse.org
#
# Contributors:
#
# * Gavin Sinclair -- gsinclair(at)soyabean.com.au
# * George Marrows -- george.marrows(at)ntlworld.com
# * Dick Davies -- rasputnik(at)hellooperator.net
# * Mauricio Fernandez -- batsman.geo(at)yahoo.com
# * Simon Strandgaard -- neoneye(at)adslhome.dk
# * Dave Glasser -- glasser(at)mit.edu
# * Paul Duncan -- pabs(at)pablotron.org
# * Ville Aine -- vaine(at)cs.helsinki.fi
# * Eric Hodel -- drbrain(at)segment7.net
# * Daniel Berger -- djberg96(at)gmail.com
# * Phil Hagelberg -- technomancy(at)gmail.com
# * Ryan Davis -- ryand-ruby(at)zenspider.com
#
# (If your name is missing, PLEASE let us know!)
#
# Thanks!
#
# -The RubyGems Team
module Gem
RubyGemsVersion = VERSION = '1.3.6'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
# name and version requirements of the gem that either conflicts with
# already activated gems or that RubyGems is otherwise unable to activate.
class LoadError < ::LoadError
# Name of gem
attr_accessor :name
# Version requirement of gem
attr_accessor :version_requirement
end
##
# Configuration settings from ::RbConfig
ConfigMap = {} unless defined?(ConfigMap)
require 'rbconfig'
ConfigMap.merge!(
:EXEEXT => RbConfig::CONFIG["EXEEXT"],
:RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
:arch => RbConfig::CONFIG["arch"],
:bindir => RbConfig::CONFIG["bindir"],
:datadir => RbConfig::CONFIG["datadir"],
:libdir => RbConfig::CONFIG["libdir"],
:ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
:ruby_version => RbConfig::CONFIG["ruby_version"],
:sitedir => RbConfig::CONFIG["sitedir"],
:sitelibdir => RbConfig::CONFIG["sitelibdir"],
:vendordir => RbConfig::CONFIG["vendordir"] ,
:vendorlibdir => RbConfig::CONFIG["vendorlibdir"]
)
##
# Default directories in a gem repository
DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
# :stopdoc:
MUTEX = Mutex.new
RubyGemsPackageVersion = RubyGemsVersion
# :startdoc:
##
# An Array of Regexps that match windows ruby platforms.
WIN_PATTERNS = [
/bccwin/i,
/cygwin/i,
/djgpp/i,
/mingw/i,
/mswin/i,
/wince/i,
]
@@source_index = nil
@@win_platform = nil
@configuration = nil
@loaded_specs = {}
@loaded_stacks = {}
@platforms = []
@ruby = nil
@sources = []
@post_install_hooks ||= []
@post_uninstall_hooks ||= []
@pre_uninstall_hooks ||= []
@pre_install_hooks ||= []
##
# Activates an installed gem matching +gem+. The gem must satisfy
# +version_requirements+.
#
# Returns true if the gem is activated, false if it is already
# loaded, or an exception otherwise.
#
# Gem#activate adds the library paths in +gem+ to $LOAD_PATH. Before a Gem
# is activated its required Gems are activated. If the version information
# is omitted, the highest version Gem of the supplied name is loaded. If a
# Gem is not found that meets the version requirements or a required Gem is
# not found, a Gem::LoadError is raised.
#
# More information on version requirements can be found in the
# Gem::Requirement and Gem::Version documentation.
def self.activate(gem, *version_requirements)
if version_requirements.last.is_a?(Hash)
options = version_requirements.pop
else
options = {}
end
sources = options[:sources] || []
if version_requirements.empty? then
version_requirements = Gem::Requirement.default
end
unless gem.respond_to?(:name) and
gem.respond_to?(:requirement) then
gem = Gem::Dependency.new(gem, version_requirements)
end
matches = Gem.source_index.find_name(gem.name, gem.requirement)
report_activate_error(gem) if matches.empty?
if @loaded_specs[gem.name] then
# This gem is already loaded. If the currently loaded gem is not in the
# list of candidate gems, then we have a version conflict.
existing_spec = @loaded_specs[gem.name]
unless matches.any? { |spec| spec.version == existing_spec.version } then
sources_message = sources.map { |spec| spec.full_name }
stack_message = @loaded_stacks[gem.name].map { |spec| spec.full_name }
msg = "can't activate #{gem} for #{sources_message.inspect}, "
msg << "already activated #{existing_spec.full_name} for "
msg << "#{stack_message.inspect}"
e = Gem::LoadError.new msg
e.name = gem.name
e.version_requirement = gem.requirement
raise e
end
return false
end
# new load
spec = matches.last
return false if spec.loaded?
spec.loaded = true
@loaded_specs[spec.name] = spec
@loaded_stacks[spec.name] = sources.dup
# Load dependent gems first
spec.runtime_dependencies.each do |dep_gem|
activate dep_gem, :sources => [spec, *sources]
end
# bin directory must come before library directories
spec.require_paths.unshift spec.bindir if spec.bindir
require_paths = spec.require_paths.map do |path|
File.join spec.full_gem_path, path
end
sitelibdir = ConfigMap[:sitelibdir]
# gem directories must come after -I and ENV['RUBYLIB']
insert_index = load_path_insert_index
if insert_index then
# gem directories must come after -I and ENV['RUBYLIB']
$LOAD_PATH.insert(insert_index, *require_paths)
else
# we are probably testing in core, -I and RUBYLIB don't apply
$LOAD_PATH.unshift(*require_paths)
end
return true
end
##
# An Array of all possible load paths for all versions of all gems in the
# Gem installation.
def self.all_load_paths
result = []
Gem.path.each do |gemdir|
each_load_path all_partials(gemdir) do |load_path|
result << load_path
end
end
result
end
##
# Return all the partial paths in +gemdir+.
def self.all_partials(gemdir)
Dir[File.join(gemdir, 'gems/*')]
end
private_class_method :all_partials
##
# See if a given gem is available.
def self.available?(gem, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
unless gem.respond_to?(:name) and
gem.respond_to?(:requirement) then
gem = Gem::Dependency.new gem, requirements
end
!Gem.source_index.search(gem).empty?
end
##
# Find the full path to the executable for gem +name+. If the +exec_name+
# is not given, the gem's default_executable is chosen, otherwise the
# specifed executable's path is returned. +version_requirements+ allows you
# to specify specific gem versions.
def self.bin_path(name, exec_name = nil, *version_requirements)
version_requirements = Gem::Requirement.default if
version_requirements.empty?
spec = Gem.source_index.find_name(name, version_requirements).last
raise Gem::GemNotFoundException,
"can't find gem #{name} (#{version_requirements})" unless spec
exec_name ||= spec.default_executable
unless exec_name
msg = "no default executable for #{spec.full_name}"
raise Gem::Exception, msg
end
unless spec.executables.include? exec_name
msg = "can't find executable #{exec_name} for #{spec.full_name}"
raise Gem::Exception, msg
end
File.join(spec.full_gem_path, spec.bindir, exec_name)
end
##
# The mode needed to read a file as straight binary.
def self.binary_mode
@binary_mode ||= RUBY_VERSION > '1.9' ? 'rb:ascii-8bit' : 'rb'
end
##
# The path where gem executables are to be installed.
def self.bindir(install_dir=Gem.dir)
return File.join(install_dir, 'bin') unless
install_dir.to_s == Gem.default_dir
Gem.default_bindir
end
##
# Reset the +dir+ and +path+ values. The next time +dir+ or +path+
# is requested, the values will be calculated from scratch. This is
# mainly used by the unit tests to provide test isolation.
def self.clear_paths
@gem_home = nil
@gem_path = nil
@user_home = nil
@@source_index = nil
MUTEX.synchronize do
@searcher = nil
end
end
##
# The path to standard location of the user's .gemrc file.
def self.config_file
File.join Gem.user_home, '.gemrc'
end
##
# The standard configuration object for gems.
def self.configuration
@configuration ||= Gem::ConfigFile.new []
end
##
# Use the given configuration object (which implements the ConfigFile
# protocol) as the standard configuration object.
def self.configuration=(config)
@configuration = config
end
##
# The path the the data directory specified by the gem name. If the
# package is not available as a gem, return nil.
def self.datadir(gem_name)
spec = @loaded_specs[gem_name]
return nil if spec.nil?
File.join(spec.full_gem_path, 'data', gem_name)
end
##
# A Zlib::Deflate.deflate wrapper
def self.deflate(data)
require 'zlib'
Zlib::Deflate.deflate data
end
##
# The path where gems are to be installed.
def self.dir
@gem_home ||= nil
set_home(ENV['GEM_HOME'] || Gem.configuration.home || default_dir) unless @gem_home
@gem_home
end
##
# Expand each partial gem path with each of the required paths specified
# in the Gem spec. Each expanded path is yielded.
def self.each_load_path(partials)
partials.each do |gp|
base = File.basename(gp)
specfn = File.join(dir, "specifications", base + ".gemspec")
if File.exist?(specfn)
spec = eval(File.read(specfn))
spec.require_paths.each do |rp|
yield(File.join(gp, rp))
end
else
filename = File.join(gp, 'lib')
yield(filename) if File.exist?(filename)
end
end
end
private_class_method :each_load_path
##
# Quietly ensure the named Gem directory contains all the proper
# subdirectories. If we can't create a directory due to a permission
# problem, then we will silently continue.
def self.ensure_gem_subdirectories(gemdir)
require 'fileutils'
Gem::DIRECTORIES.each do |filename|
fn = File.join gemdir, filename
FileUtils.mkdir_p fn rescue nil unless File.exist? fn
end
end
##
# Returns a list of paths matching +file+ that can be used by a gem to pick
# up features from other gems. For example:
#
# Gem.find_files('rdoc/discover').each do |path| load path end
#
# find_files search $LOAD_PATH for files as well as gems.
#
# Note that find_files will return all files even if they are from different
# versions of the same gem.
def self.find_files(path)
load_path_files = $LOAD_PATH.map do |load_path|
files = Dir["#{File.expand_path path, load_path}#{Gem.suffix_pattern}"]
files.select do |load_path_file|
File.file? load_path_file.untaint
end
end.flatten
specs = searcher.find_all path
specs_files = specs.map do |spec|
searcher.matching_files spec, path
end.flatten
(load_path_files + specs_files).flatten.uniq
end
##
# Finds the user's home directory.
#--
# Some comments from the ruby-talk list regarding finding the home
# directory:
#
# I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
# to be depending on HOME in those code samples. I propose that
# it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
# least on Win32).
def self.find_home
unless RUBY_VERSION > '1.9' then
['HOME', 'USERPROFILE'].each do |homekey|
return ENV[homekey] if ENV[homekey]
end
if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
end
end
File.expand_path "~"
rescue
if File::ALT_SEPARATOR then
"C:/"
else
"/"
end
end
private_class_method :find_home
##
# Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data)
require 'stringio'
require 'zlib'
data = StringIO.new data
Zlib::GzipReader.new(data).read
end
##
# Zlib::GzipWriter wrapper that zips +data+.
def self.gzip(data)
require 'stringio'
require 'zlib'
zipped = StringIO.new
Zlib::GzipWriter.wrap zipped do |io| io.write data end
zipped.string
end
##
# A Zlib::Inflate#inflate wrapper
def self.inflate(data)
require 'zlib'
Zlib::Inflate.inflate data
end
##
# Return a list of all possible load paths for the latest version for all
# gems in the Gem installation.
def self.latest_load_paths
result = []
Gem.path.each do |gemdir|
each_load_path(latest_partials(gemdir)) do |load_path|
result << load_path
end
end
result
end
##
# Return only the latest partial paths in the given +gemdir+.
def self.latest_partials(gemdir)
latest = {}
all_partials(gemdir).each do |gp|
base = File.basename(gp)
if base =~ /(.*)-((\d+\.)*\d+)/ then
name, version = $1, $2
ver = Gem::Version.new(version)
if latest[name].nil? || ver > latest[name][0]
latest[name] = [ver, gp]
end
end
end
latest.collect { |k,v| v[1] }
end
private_class_method :latest_partials
##
# The index to insert activated gem paths into the $LOAD_PATH.
#
# Defaults to the site lib directory unless gem_prelude.rb has loaded paths,
# then it inserts the activated gem's paths before the gem_prelude.rb paths
# so you can override the gem_prelude.rb default $LOAD_PATH paths.
def self.load_path_insert_index
index = $LOAD_PATH.index ConfigMap[:sitelibdir]
$LOAD_PATH.each_with_index do |path, i|
if path.instance_variables.include?(:@gem_prelude_index) or
path.instance_variables.include?('@gem_prelude_index') then
index = i
break
end
end
index
end
##
# The file name and line number of the caller of the caller of this method.
def self.location_of_caller
caller[1] =~ /(.*?):(\d+).*?$/i
file = $1
lineno = $2.to_i
[file, lineno]
end
##
# The version of the Marshal format for your Ruby.
def self.marshal_version
"#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
end
##
# Array of paths to search for Gems.
def self.path
@gem_path ||= nil
unless @gem_path then
paths = [ENV['GEM_PATH'] || Gem.configuration.path || default_path]
if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then
paths << APPLE_GEM_HOME
end
set_paths paths.compact.join(File::PATH_SEPARATOR)
end
@gem_path
end
##
# Set array of platforms this RubyGems supports (primarily for testing).
def self.platforms=(platforms)
@platforms = platforms
end
##
# Array of platforms this RubyGems supports.
def self.platforms
@platforms ||= []
if @platforms.empty?
@platforms = [Gem::Platform::RUBY, Gem::Platform.local]
end
@platforms
end
##
# Adds a post-install hook that will be passed an Gem::Installer instance
# when Gem::Installer#install is called
def self.post_install(&hook)
@post_install_hooks << hook
end
##
# Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance
# and the spec that was uninstalled when Gem::Uninstaller#uninstall is
# called
def self.post_uninstall(&hook)
@post_uninstall_hooks << hook
end
##
# Adds a pre-install hook that will be passed an Gem::Installer instance
# when Gem::Installer#install is called
def self.pre_install(&hook)
@pre_install_hooks << hook
end
##
# Adds a pre-uninstall hook that will be passed an Gem::Uninstaller instance
# and the spec that will be uninstalled when Gem::Uninstaller#uninstall is
# called
def self.pre_uninstall(&hook)
@pre_uninstall_hooks << hook
end
##
# The directory prefix this RubyGems was installed at.
def self.prefix
prefix = File.dirname File.expand_path(__FILE__)
if File.dirname(prefix) == File.expand_path(ConfigMap[:sitelibdir]) or
File.dirname(prefix) == File.expand_path(ConfigMap[:libdir]) or
'lib' != File.basename(prefix) then
nil
else
File.dirname prefix
end
end
##
# Promotes the load paths of the +gem_name+ over the load paths of
# +over_name+. Useful for allowing one gem to override features in another
# using #find_files.
def self.promote_load_path(gem_name, over_name)
gem = Gem.loaded_specs[gem_name]
over = Gem.loaded_specs[over_name]
raise ArgumentError, "gem #{gem_name} is not activated" if gem.nil?
raise ArgumentError, "gem #{over_name} is not activated" if over.nil?
last_gem_path = File.join gem.full_gem_path, gem.require_paths.last
over_paths = over.require_paths.map do |path|
File.join over.full_gem_path, path
end
over_paths.each do |path|
$LOAD_PATH.delete path
end
gem = $LOAD_PATH.index(last_gem_path) + 1
$LOAD_PATH.insert(gem, *over_paths)
end
##
# Refresh source_index from disk and clear searcher.
def self.refresh
source_index.refresh!
MUTEX.synchronize do
@searcher = nil
end
end
##
# Safely read a file in binary mode on all platforms.
def self.read_binary(path)
File.open path, binary_mode do |f| f.read end
end
##
# Report a load error during activation. The message of load error
# depends on whether it was a version mismatch or if there are not gems of
# any version by the requested name.
def self.report_activate_error(gem)
matches = Gem.source_index.find_name(gem.name)
if matches.empty? then
error = Gem::LoadError.new(
"Could not find RubyGem #{gem.name} (#{gem.requirement})\n")
else
error = Gem::LoadError.new(
"RubyGem version error: " +
"#{gem.name}(#{matches.first.version} not #{gem.requirement})\n")
end
error.name = gem.name
error.version_requirement = gem.requirement
raise error
end
private_class_method :report_activate_error
##
# Full path to +libfile+ in +gemname+. Searches for the latest gem unless
# +requirements+ is given.
def self.required_location(gemname, libfile, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
matches = Gem.source_index.find_name gemname, requirements
return nil if matches.empty?
spec = matches.last
spec.require_paths.each do |path|
result = File.join spec.full_gem_path, path, libfile
return result if File.exist? result
end
nil
end
##
# The path to the running Ruby interpreter.
def self.ruby
if @ruby.nil? then
@ruby = File.join(ConfigMap[:bindir],
ConfigMap[:ruby_install_name])
@ruby << ConfigMap[:EXEEXT]
# escape string in case path to ruby executable contain spaces.
@ruby.sub!(/.*\s.*/m, '"\&"')
end
@ruby
end
##
# A Gem::Version for the currently running ruby.
def self.ruby_version
return @ruby_version if defined? @ruby_version
version = RUBY_VERSION.dup
if defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL != -1 then
version << ".#{RUBY_PATCHLEVEL}"
elsif defined?(RUBY_REVISION) then
version << ".dev.#{RUBY_REVISION}"
end
@ruby_version = Gem::Version.new version
end
##
# The GemPathSearcher object used to search for matching installed gems.
def self.searcher
MUTEX.synchronize do
@searcher ||= Gem::GemPathSearcher.new
end
end
##
# Set the Gem home directory (as reported by Gem.dir).
def self.set_home(home)
home = home.gsub File::ALT_SEPARATOR, File::SEPARATOR if File::ALT_SEPARATOR
@gem_home = home
end
private_class_method :set_home
##
# Set the Gem search path (as reported by Gem.path).
def self.set_paths(gpaths)
if gpaths
@gem_path = gpaths.split(File::PATH_SEPARATOR)
if File::ALT_SEPARATOR then
@gem_path.map! do |path|
path.gsub File::ALT_SEPARATOR, File::SEPARATOR
end
end
@gem_path << Gem.dir
else
# TODO: should this be Gem.default_path instead?
@gem_path = [Gem.dir]
end
@gem_path.uniq!
end
private_class_method :set_paths
##
# Returns the Gem::SourceIndex of specifications that are in the Gem.path
def self.source_index
@@source_index ||= SourceIndex.from_installed_gems
end
##
# Returns an Array of sources to fetch remote gems from. If the sources
# list is empty, attempts to load the "sources" gem, then uses
# default_sources if it is not installed.
def self.sources
if @sources.empty? then
begin
gem 'sources', '> 0.0.1'
require 'sources'
rescue LoadError
@sources = default_sources
end
end
@sources
end
##
# Need to be able to set the sources without calling
# Gem.sources.replace since that would cause an infinite loop.
def self.sources=(new_sources)
@sources = new_sources
end
##
# Glob pattern for require-able path suffixes.
def self.suffix_pattern
@suffix_pattern ||= "{#{suffixes.join(',')}}"
end
##
# Suffixes for require-able paths.
def self.suffixes
['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
end
##
# Prints the amount of time the supplied block takes to run using the debug
# UI output.
def self.time(msg, width = 0, display = Gem.configuration.verbose)
now = Time.now
value = yield
elapsed = Time.now - now
ui.say "%2$*1$s: %3$3.3fs" % [-width, msg, elapsed] if display
value
end
##
# Lazily loads DefaultUserInteraction and returns the default UI.
def self.ui
require 'rubygems/user_interaction'
Gem::DefaultUserInteraction.ui
end
##
# Use the +home+ and +paths+ values for Gem.dir and Gem.path. Used mainly
# by the unit tests to provide environment isolation.
def self.use_paths(home, paths=[])
clear_paths
set_home(home) if home
set_paths(paths.join(File::PATH_SEPARATOR)) if paths
end
##
# The home directory for the user.
def self.user_home
@user_home ||= find_home
end
##
# Is this a windows platform?
def self.win_platform?
if @@win_platform.nil? then
@@win_platform = !!WIN_PATTERNS.find { |r| RUBY_PLATFORM =~ r }
end
@@win_platform
end
class << self
##
# Hash of loaded Gem::Specification keyed by name
attr_reader :loaded_specs
##
# The list of hooks to be run before Gem::Install#install does any work
attr_reader :post_install_hooks
##
# The list of hooks to be run before Gem::Uninstall#uninstall does any
# work
attr_reader :post_uninstall_hooks
##
# The list of hooks to be run after Gem::Install#install is finished
attr_reader :pre_install_hooks
##
# The list of hooks to be run after Gem::Uninstall#uninstall is finished
attr_reader :pre_uninstall_hooks
# :stopdoc:
alias cache source_index # an alias for the old name
# :startdoc:
end
##
# Location of Marshal quick gemspecs on remote repositories
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
##
# Location of legacy YAML quick gemspecs on remote repositories
YAML_SPEC_DIR = 'quick/'
end
module Kernel
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
# +version_requirements+ is a list of version requirements that the
# specified gem must match, most commonly "= example.version.number". See
# Gem::Requirement for how to specify a version requirement.
#
# If you will be activating the latest version of a gem, there is no need to
# call Kernel#gem, Kernel#require will do the right thing for you.
#
# Kernel#gem returns true if the gem was activated, otherwise false. If the
# gem could not be found, didn't match the version requirements, or a
# different version was already activated, an exception will be raised.
#
# Kernel#gem should be called *before* any require statements (otherwise
# RubyGems may load a conflicting library version).
#
# In older RubyGems versions, the environment variable GEM_SKIP could be
# used to skip activation of specified gems, for example to test out changes
# that haven't been installed yet. Now RubyGems defers to -I and the
# RUBYLIB environment variable to skip activation of a gem.
#
# Example:
#
# GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
def gem(gem_name, *version_requirements) # :doc:
skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
Gem.activate(gem_name, *version_requirements)
end
private :gem
end
##
# Return the path to the data directory associated with the named package. If
# the package is loaded as a gem, return the gem specific data directory.
# Otherwise return a path to the share area as define by
# "#{ConfigMap[:datadir]}/#{package_name}".
def RbConfig.datadir(package_name)
Gem.datadir(package_name) ||
File.join(Gem::ConfigMap[:datadir], package_name)
end
require 'rubygems/exceptions'
require 'rubygems/version'
require 'rubygems/requirement'
require 'rubygems/dependency'
require 'rubygems/gem_path_searcher' # Needed for Kernel#gem
require 'rubygems/source_index' # Needed for Kernel#gem
require 'rubygems/platform'
require 'rubygems/builder' # HACK: Needed for rake's package task.
begin
require 'rubygems/defaults/operating_system'
rescue LoadError
end
if defined?(RUBY_ENGINE) then
begin
require "rubygems/defaults/#{RUBY_ENGINE}"
rescue LoadError
end
end
require 'rubygems/config_file'
if RUBY_VERSION < '1.9' then
require 'rubygems/custom_require'
end
Gem.clear_paths
plugins = Gem.find_files 'rubygems_plugin'
plugins.each do |plugin|
# Skip older versions of the GemCutter plugin: Its commands are in
# RubyGems proper now.
next if plugin =~ /gemcutter-0\.[0-3]/
begin
load plugin
rescue => e
warn "error loading #{plugin.inspect}: #{e.message} (#{e.class})"
end
end
|