Temporary tag for this failure. Updated CI spec coming.
[rbx.git] / kernel / core / gem_prelude.rb
blobe727bee876e76999f55da4d838cb9fa8227e6320
1 # depends on: array.rb dir.rb env.rb file.rb hash.rb module.rb regexp.rb
3 # empty gem_prelude.rb
5 # p Gem::Enable
7 if defined?(Gem::Enable) && Gem::Enable then
9   module Kernel
11     def gem(gem_name, *version_requirements)
12       Gem.push_gem_version_on_load_path(gem_name, *version_requirements)
13     end
15   end
17   module Gem
19     ConfigMap = {
20       :sitedir => RbConfig::CONFIG["sitedir"],
21       :ruby_version => RbConfig::CONFIG["ruby_version"],
22       :libdir => RbConfig::CONFIG["libdir"],
23       :sitelibdir => RbConfig::CONFIG["sitelibdir"],
24       :arch => RbConfig::CONFIG["arch"],
25       :bindir => RbConfig::CONFIG["bindir"],
26       :EXEEXT => RbConfig::CONFIG["EXEEXT"],
27       :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
28       :ruby_install_name => RbConfig::CONFIG["ruby_install_name"]
29     }
31     class << self
33       def default_dir
34         if defined? RUBY_FRAMEWORK_VERSION
35           return File.join(File.dirname(ConfigMap[:sitedir]), "Gems")
36         else
37           File.join(ConfigMap[:libdir], 'ruby', 'gems', ConfigMap[:ruby_version])
38         end
39       end
41       def dir
42         @gem_home ||= nil
43         set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
44         @gem_home
45       end
47       def path
48         @gem_path ||= nil
49         unless @gem_path
50           paths = [ENV['GEM_PATH']]
51           paths << APPLE_GEM_HOME if defined? APPLE_GEM_HOME
52           set_paths(paths.compact.join(File::PATH_SEPARATOR))
53         end
54         @gem_path
55       end
57       # Set the Gem home directory (as reported by +dir+).
58       def set_home(home)
59         @gem_home = home
60         ensure_gem_subdirectories(@gem_home)
61       end
63       def set_paths(gpaths)
64         if gpaths
65           @gem_path = gpaths.split(File::PATH_SEPARATOR)
66           @gem_path << Gem.dir
67         else
68           @gem_path = [Gem.dir]
69         end
70         @gem_path.uniq!
71         @gem_path.each do |gp| ensure_gem_subdirectories(gp) end
72       end
74       def ensure_gem_subdirectories(path)
75       end
77     end
79     module QuickLoader
81       class << self
82         def load_full_rubygems_library
83           class << Gem
84             Gem.methods(false).each do |method_name|
85               undef_method method_name
86             end
87           end
89           Kernel.send :undef_method, :gem
91           $".delete File.join(Gem::ConfigMap[:libdir], 'ruby',
92                               Gem::ConfigMap[:ruby_version], 'rubygems.rb')
94           require 'rubygems'
95         end
96       end
98       GemPaths = {}
99       GemVersions = {}
101       def push_gem_version_on_load_path(gem_name, *version_requirements)
102         if version_requirements.empty?
103           unless GemPaths.has_key?(gem_name)
104             raise LoadError.new("Could not find RubyGem #{gem_name} (>= 0)\n") 
105           end
107           # highest version gems already active
108           return false
109         else
110           if version_requirements.length > 1
111             QuickLoader.load_full_rubygems_library
112             return gem(gem_name, *version_requirements)
113           end
115           requirement, version = version_requirements[0].split
116           requirement.strip!
118           if requirement == ">" || requirement == ">="
119             if (GemVersions[gem_name] <=> Gem.calculate_integers_for_gem_version(version)) >= 0
120               return false 
121             end
122           elsif requirement == "~>"
123             loaded_version = GemVersions[gem_name]
124             required_version = Gem.calculate_integers_for_gem_version(version)
125             if loaded_version && (loaded_version[0] == required_version[0])
126               return false
127             end
128           end
130           QuickLoader.load_full_rubygems_library
131           gem(gem_name, *version_requirements)
132         end
133       end
135       def calculate_integers_for_gem_version(gem_version)
136         numbers = gem_version.split(".").collect {|n| n.to_i}
137         numbers.pop while numbers.last == 0
138         numbers << 0 if numbers.empty?
139         numbers
140       end
142       def push_all_highest_version_gems_on_load_path
143         Gem.path.each do |path|
144           gems_directory = File.join(path, "gems")
145           if File.exist?(gems_directory)
146             Dir.entries(gems_directory).each do |gem_directory_name|
147               next if gem_directory_name == "." || gem_directory_name == ".."
148               dash = gem_directory_name.rindex("-")
149               next if dash.nil?
150               gem_name = gem_directory_name[0...dash]
151               current_version = GemVersions[gem_name]
152               new_version = calculate_integers_for_gem_version(gem_directory_name[dash+1..-1])
153               if current_version
154                 if (current_version <=> new_version) == -1
155                   GemVersions[gem_name] = new_version
156                   GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)
157                 end
158               else
159                 GemVersions[gem_name] = new_version
160                 GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)
161               end
162             end
163           end
164         end
166         require_paths = []
168         GemPaths.values.each do |path|
169           if File.exist?(File.join(path, ".require_paths"))
170             require_paths.concat(File.read(File.join(path, ".require_paths")).split.map {|require_path| File.join(path, require_path)})
171           else
172             require_paths << File.join(path, "bin") if File.exist?(File.join(path, "bin"))
173             require_paths << File.join(path, "lib") if File.exist?(File.join(path, "lib"))
174           end
175         end
177         # "tag" the first require_path inserted into the $LOAD_PATH to enable
178         # indexing correctly with rubygems proper when it inserts an explicitly
179         # gem version
180         unless require_paths.empty?
181           require_paths.first.instance_variable_set(:@gem_prelude_index, true)
182         end
183         # gem directories must come after -I and ENV['RUBYLIB']
184         $:[$:.index(ConfigMap[:sitelibdir]),0] = require_paths
185       end
187       def const_missing(constant)
188         QuickLoader.load_full_rubygems_library
189         Gem.const_get(constant)
190       end
192       def method_missing(method, *args, &block)
193         QuickLoader.load_full_rubygems_library
194         super unless Gem.respond_to?(method)
195         Gem.send(method, *args, &block)
196       end
197     end
199     extend QuickLoader
201   end
203   begin
204     Gem.push_all_highest_version_gems_on_load_path
205     $" << File.join(Gem::ConfigMap[:libdir], "ruby",
206                     Gem::ConfigMap[:ruby_version], "rubygems.rb")
207   rescue Exception => e
208     puts "Error loading gem paths on load path in gem_prelude"
209     puts e
210     puts e.backtrace.join("\n")
211   end