faster_rubygems 0.2.1 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +34 -25
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/examples/require_fast_start.rb +7 -3
- data/examples/require_rubygems_normal.rb +7 -3
- data/ext/mkrf_conf.rb +3 -4
- data/{install.rb → internalize.rb} +0 -2
- data/lib/faster_rubygems/install.rb +29 -0
- data/lib/faster_rubygems.rb +7 -32
- data/lib/my_defaults.rb +101 -0
- data/lib/my_gem_prelude.rb +313 -0
- data/lib/prelude_bin_path.rb +59 -0
- data/spec/common.rb +0 -0
- data/spec/spec.faster_rubygems_cacheing.rb +31 -0
- metadata +76 -18
- data/lib/faster_rubygems_lib.rb +0 -64
- data/lib/ubygemsf.rb +0 -1
- data/spec/spec.faster_rubygems.rb +0 -55
data/README
CHANGED
@@ -1,58 +1,67 @@
|
|
1
|
-
A helper to dramatically speedup the time it takes to load rubygems
|
1
|
+
A helper to dramatically speedup the time it takes to load rubygems.
|
2
2
|
|
3
|
-
i.e. "require 'rubygems'" no longer has to sap valuable time from your life.
|
4
|
-
|
5
|
-
inspired by a request from Yehuda Katz [1] and 1.9's fast gem_prelude.
|
3
|
+
i.e. it makes it so that "require 'rubygems'" no longer has to sap valuable time from your life.
|
6
4
|
|
7
5
|
Speed difference (windows box, lots of gem):
|
8
6
|
|
9
7
|
$ time ruby examples/require_rubygems_normal.rb
|
10
|
-
|
11
8
|
real 0m1.109s
|
12
9
|
|
13
10
|
$ time ruby examples/require_fast_start.rb
|
14
|
-
|
15
11
|
real 0m0.500s
|
16
12
|
|
17
|
-
Yea! Finally ruby script startup times that don't spend forever just reloading gem
|
13
|
+
Yea! Finally ruby script startup times that don't spend forever just reloading gem specs every single time...
|
18
14
|
|
19
15
|
It acts about the same as gem_prelude (prelude is 1.9 only currently) -- adds the paths of the highest version of each gem into your load path so they're ready to be required.
|
20
16
|
|
17
|
+
It is also good for 1.9 makes script startup faster. To use it with 1.9 do an
|
18
|
+
$ export RUBYOPTS=-rfaster_rubygems
|
19
|
+
|
20
|
+
somewhere.
|
21
|
+
|
21
22
|
== installation ==
|
22
23
|
|
23
|
-
|
24
|
-
ruby faster_rubygems/install.rb # done
|
24
|
+
$ gem install faster_rubygems
|
25
25
|
|
26
26
|
== usage ==
|
27
|
-
require 'frubygems'
|
28
|
-
or
|
29
|
-
require 'rubygemsf'
|
30
27
|
|
31
|
-
|
28
|
+
1.9:
|
29
|
+
$ export RUBYOPTS=-rfaster_rubygems
|
30
|
+
|
31
|
+
1.8:
|
32
|
+
|
33
|
+
require 'faster_rubygems'
|
34
|
+
at the top of your script, or install it to be used by default thus:
|
32
35
|
|
33
|
-
|
36
|
+
>> require 'rubygems'
|
37
|
+
>> require 'faster_rubygems/install'
|
38
|
+
>> FasterRubyGems.install_over_rubygems! # installs this to be the default for rubygems
|
34
39
|
|
35
|
-
|
40
|
+
|
41
|
+
# later, to revert back to normal, should you so desire:
|
42
|
+
>> require 'rubygems'
|
43
|
+
>> require 'faster_rubygems/install'
|
44
|
+
>> FasterRubyGems.uninstall_over_rubygems!
|
45
|
+
|
46
|
+
If all else fails, you can reinstall rubygems by running setup.rb from within its package: http://rubyforge.org/frs/?group_id=126
|
47
|
+
|
48
|
+
== More Speed Comparisons ==
|
36
49
|
|
37
50
|
For those interested, speed difference example on linux (250 gems):
|
51
|
+
|
38
52
|
$ time ruby examples/require_rubygems_normal.rb
|
39
|
-
ruby examples/require_rubygems_normal.rb 0.57s user 0.05s system 85%
|
40
|
-
cpu 0.726 total
|
53
|
+
ruby examples/require_rubygems_normal.rb 0.57s user 0.05s system 85% cpu 0.726 total
|
41
54
|
|
42
55
|
$ time ruby examples/require_fast_start.rb
|
43
|
-
ruby examples/require_fast_start.rb 0.04s user 0.02s system 46% cpu
|
44
|
-
0.121 total
|
56
|
+
ruby examples/require_fast_start.rb 0.04s user 0.02s system 46% cpu 0.121 total
|
45
57
|
|
46
58
|
Note also that a few non conforming gems require the use of require 'rubygems' no matter what (they're pretty rare, though--you probably won't run into them, and I'm not aware of any).
|
47
59
|
|
48
|
-
Note: you don't need this for ruby 1.9, which already preloads via gem_prelude, but it won't hurt to use it in 1.9--it defaults to a no-op, so doesn't hurt.
|
49
|
-
|
50
60
|
Related projects:
|
51
61
|
|
52
62
|
http://github.com/fabien/minigems/tree/master
|
53
|
-
1.9's gem_prelude
|
63
|
+
1.9's gem_prelude.rb
|
54
64
|
http://www.ruby-forum.com/topic/191673
|
55
65
|
|
56
|
-
|
57
|
-
|
58
|
-
[1] http://rubyforge.org/tracker/index.php?func=detail&aid=21288&group_id=126&atid=578
|
66
|
+
Source/contact:
|
67
|
+
http://www.github.com/rdp/faster_rubygems
|
data/Rakefile
CHANGED
@@ -11,7 +11,9 @@ require 'jeweler'
|
|
11
11
|
installed! use -> require 'faster_rubygems'
|
12
12
|
|
13
13
|
"
|
14
|
-
|
15
14
|
s.add_development_dependency 'test-unit', '=1.2.3'
|
16
15
|
s.add_development_dependency 'test-unit', '=2.0.6'
|
17
|
-
|
16
|
+
s.add_development_dependency 'after', '=0.7.0'
|
17
|
+
s.add_development_dependency 'sane'
|
18
|
+
|
19
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.1
|
@@ -1,3 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
1
|
+
require 'benchmark'
|
2
|
+
puts Benchmark.realtime {
|
3
|
+
require File.dirname(__FILE__) + '/../lib/faster_rubygems'
|
4
|
+
gem 'ruby-prof'
|
5
|
+
Gem.bin_path 'ruby-prof'
|
6
|
+
require 'ruby-prof' # load a gem
|
7
|
+
}
|
data/ext/mkrf_conf.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
#
|
3
|
+
# do some ruby stuff...
|
4
4
|
|
5
5
|
puts File.dirname(__FILE__)
|
6
|
-
|
7
|
-
load a
|
6
|
+
load File.expand_path(File.dirname(__FILE__)) + "/../internalize.rb" # install this gem locally
|
8
7
|
|
9
|
-
f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w")
|
8
|
+
f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w") # create dummy rakefile to indicate success
|
10
9
|
f.write("task :default\n")
|
11
10
|
f.close
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module FasterRubyGems
|
3
|
+
def self.install_over_rubygems!
|
4
|
+
raise 'only needed on 1.8 -- for 1.9 you have to \n $ export RUBYOPT=$RUBYOPT -rfaster_rubygems' if RUBY_VERSION >= '1.9.0'
|
5
|
+
require 'fileutils'
|
6
|
+
old = rubygems_path
|
7
|
+
FileUtils.cp old, old + ".bak.rb"
|
8
|
+
File.open(old, 'w') do |f|
|
9
|
+
f.write "require 'faster_rubygems'"
|
10
|
+
end
|
11
|
+
'success--it will load by default in place of normal rubygems'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.rubygems_path
|
15
|
+
Gem::Dependency
|
16
|
+
raise unless $LOADED_FEATURES.include? "rubygems.rb"
|
17
|
+
# now go and look for it
|
18
|
+
$:.detect{|path| File.exist?(path + '/rubygems.rb') || File.exist?(path + '/rubygems.bak.rb')} + "/rubygems.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.uninstall_over_rubygems!
|
22
|
+
raise 'only needed on 1.8' if RUBY_VERSION >= '1.9.0'
|
23
|
+
require 'fileutils'
|
24
|
+
old = rubygems_path + ".bak.rb"
|
25
|
+
FileUtils.cp old, rubygems_path
|
26
|
+
File.delete old
|
27
|
+
'success!'
|
28
|
+
end
|
29
|
+
end
|
data/lib/faster_rubygems.rb
CHANGED
@@ -1,33 +1,8 @@
|
|
1
|
-
if RUBY_VERSION < '1.9'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
$: << path
|
6
|
-
}
|
7
|
-
|
8
|
-
module Kernel
|
9
|
-
|
10
|
-
def gem *args
|
11
|
-
undef :gem
|
12
|
-
require 'rubygems' # punt!
|
13
|
-
gem *args
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
module ::Gem
|
19
|
-
def self.const_missing const
|
20
|
-
require 'rubygems' # punt!
|
21
|
-
return Gem.const_get(const)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.method_missing meth, *args
|
25
|
-
require 'rubygems' # punt!
|
26
|
-
return Gem.send(meth, *args)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
else
|
32
|
-
# not needed in 1.9, which by default loads gem_prelude
|
1
|
+
if RUBY_VERSION < '1.9.0'
|
2
|
+
raise 'rubygems was already loaded' if defined?(Gem)
|
3
|
+
module Gem; end # define it so gem_prelude will execute...
|
4
|
+
require File.dirname(__FILE__) + "/my_gem_prelude.rb"
|
33
5
|
end
|
6
|
+
|
7
|
+
# both 1.8 and 1.9 now want this one though...
|
8
|
+
require File.dirname(__FILE__) + "/prelude_bin_path"
|
data/lib/my_defaults.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
module Gem
|
2
|
+
|
3
|
+
@post_install_hooks ||= []
|
4
|
+
@post_uninstall_hooks ||= []
|
5
|
+
@pre_uninstall_hooks ||= []
|
6
|
+
@pre_install_hooks ||= []
|
7
|
+
|
8
|
+
##
|
9
|
+
# An Array of the default sources that come with RubyGems
|
10
|
+
|
11
|
+
def self.default_sources
|
12
|
+
%w[http://rubygems.org/]
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Default home directory path to be used if an alternate value is not
|
17
|
+
# specified in the environment
|
18
|
+
|
19
|
+
def self.default_dir
|
20
|
+
if defined? RUBY_FRAMEWORK_VERSION then
|
21
|
+
File.join File.dirname(ConfigMap[:sitedir]), 'Gems',
|
22
|
+
ConfigMap[:ruby_version]
|
23
|
+
elsif ConfigMap[:rubylibprefix] then
|
24
|
+
File.join(ConfigMap[:rubylibprefix], 'gems',
|
25
|
+
ConfigMap[:ruby_version])
|
26
|
+
else
|
27
|
+
File.join(ConfigMap[:libdir], ruby_engine, 'gems',
|
28
|
+
ConfigMap[:ruby_version])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Path for gems in the user's home directory
|
34
|
+
|
35
|
+
def self.user_dir
|
36
|
+
File.join Gem.user_home, '.gem', ruby_engine, ConfigMap[:ruby_version]
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Default gem load path
|
41
|
+
|
42
|
+
def self.default_path
|
43
|
+
if File.exist? Gem.user_home then
|
44
|
+
[user_dir, default_dir]
|
45
|
+
else
|
46
|
+
[default_dir]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Deduce Ruby's --program-prefix and --program-suffix from its install name
|
52
|
+
|
53
|
+
def self.default_exec_format
|
54
|
+
exec_format = ConfigMap[:ruby_install_name].sub('ruby', '%s') rescue '%s'
|
55
|
+
|
56
|
+
unless exec_format =~ /%s/ then
|
57
|
+
raise Gem::Exception,
|
58
|
+
"[BUG] invalid exec_format #{exec_format.inspect}, no %s"
|
59
|
+
end
|
60
|
+
|
61
|
+
exec_format
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# The default directory for binaries
|
66
|
+
|
67
|
+
def self.default_bindir
|
68
|
+
if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
|
69
|
+
'/usr/bin'
|
70
|
+
else # generic install
|
71
|
+
ConfigMap[:bindir]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# The default system-wide source info cache directory
|
77
|
+
|
78
|
+
def self.default_system_source_cache_dir
|
79
|
+
File.join Gem.dir, 'source_cache'
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# The default user-specific source info cache directory
|
84
|
+
|
85
|
+
def self.default_user_source_cache_dir
|
86
|
+
File.join Gem.user_home, '.gem', 'source_cache'
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# A wrapper around RUBY_ENGINE const that may not be defined
|
91
|
+
|
92
|
+
def self.ruby_engine
|
93
|
+
if defined? RUBY_ENGINE then
|
94
|
+
RUBY_ENGINE
|
95
|
+
else
|
96
|
+
'ruby'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,313 @@
|
|
1
|
+
# copied from 1.9.2
|
2
|
+
|
3
|
+
# in reality, this file will only be ever run via 1.8
|
4
|
+
|
5
|
+
# depends on: array.rb dir.rb env.rb file.rb hash.rb module.rb regexp.rb
|
6
|
+
# vim: filetype=ruby
|
7
|
+
|
8
|
+
# NOTICE: Ruby is during initialization here.
|
9
|
+
# * Encoding.default_external does not reflects -E.
|
10
|
+
# * Should not expect Encoding.default_internal.
|
11
|
+
# * Locale encoding is available.
|
12
|
+
if defined?(Gem) then
|
13
|
+
|
14
|
+
require 'rbconfig'
|
15
|
+
# :stopdoc:
|
16
|
+
|
17
|
+
module Kernel
|
18
|
+
|
19
|
+
def gem(gem_name, *version_requirements)
|
20
|
+
Gem.push_gem_version_on_load_path(gem_name, *version_requirements)
|
21
|
+
end
|
22
|
+
private :gem
|
23
|
+
end
|
24
|
+
|
25
|
+
module Gem
|
26
|
+
|
27
|
+
ConfigMap = {
|
28
|
+
:EXEEXT => RbConfig::CONFIG["EXEEXT"],
|
29
|
+
:RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
|
30
|
+
:arch => RbConfig::CONFIG["arch"],
|
31
|
+
:bindir => RbConfig::CONFIG["bindir"],
|
32
|
+
:libdir => RbConfig::CONFIG["libdir"],
|
33
|
+
:ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
|
34
|
+
:ruby_version => RbConfig::CONFIG["ruby_version"],
|
35
|
+
:rubylibprefix => (RbConfig::CONFIG["rubylibprefix"] || RbConfig::CONFIG['rubylibdir'].split('/')[0..-2].join('/')),
|
36
|
+
:sitedir => RbConfig::CONFIG["sitedir"],
|
37
|
+
:sitelibdir => RbConfig::CONFIG["sitelibdir"],
|
38
|
+
}
|
39
|
+
|
40
|
+
def self.dir
|
41
|
+
@gem_home ||= nil
|
42
|
+
set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
|
43
|
+
@gem_home
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.path
|
47
|
+
@gem_path ||= nil
|
48
|
+
unless @gem_path
|
49
|
+
paths = [ENV['GEM_PATH'] || default_path]
|
50
|
+
paths << APPLE_GEM_HOME if defined? APPLE_GEM_HOME
|
51
|
+
set_paths(paths.compact.join(File::PATH_SEPARATOR))
|
52
|
+
end
|
53
|
+
@gem_path
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.post_install(&hook)
|
57
|
+
@post_install_hooks << hook
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.post_uninstall(&hook)
|
61
|
+
@post_uninstall_hooks << hook
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.pre_install(&hook)
|
65
|
+
@pre_install_hooks << hook
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.pre_uninstall(&hook)
|
69
|
+
@pre_uninstall_hooks << hook
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.set_home(home)
|
73
|
+
home = home.dup
|
74
|
+
home.gsub!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
75
|
+
@gem_home = home
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.set_paths(gpaths)
|
79
|
+
if gpaths
|
80
|
+
@gem_path = gpaths.split(File::PATH_SEPARATOR)
|
81
|
+
|
82
|
+
if File::ALT_SEPARATOR then
|
83
|
+
@gem_path.map! do |path|
|
84
|
+
path.gsub File::ALT_SEPARATOR, File::SEPARATOR
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
@gem_path << Gem.dir
|
89
|
+
else
|
90
|
+
# TODO: should this be Gem.default_path instead?
|
91
|
+
@gem_path = [Gem.dir]
|
92
|
+
end
|
93
|
+
|
94
|
+
@gem_path.uniq!
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.user_home
|
98
|
+
@user_home ||= File.expand_path("~")
|
99
|
+
rescue
|
100
|
+
if File::ALT_SEPARATOR then
|
101
|
+
"C:/"
|
102
|
+
else
|
103
|
+
"/"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# begin rubygems/defaults
|
108
|
+
# NOTE: this require will be replaced with in-place eval before compilation.
|
109
|
+
require File.dirname(__FILE__) + '/my_defaults.rb'
|
110
|
+
# end rubygems/defaults
|
111
|
+
|
112
|
+
|
113
|
+
##
|
114
|
+
# Methods before this line will be removed when QuickLoader is replaced
|
115
|
+
# with the real RubyGems
|
116
|
+
|
117
|
+
GEM_PRELUDE_METHODS = Gem.methods(false)
|
118
|
+
|
119
|
+
begin
|
120
|
+
verbose, debug = $VERBOSE, $DEBUG
|
121
|
+
$VERBOSE = $DEBUG = nil
|
122
|
+
|
123
|
+
begin
|
124
|
+
require 'rubygems/defaults/operating_system'
|
125
|
+
rescue ::LoadError
|
126
|
+
end
|
127
|
+
|
128
|
+
if defined?(RUBY_ENGINE) then
|
129
|
+
begin
|
130
|
+
require "rubygems/defaults/#{RUBY_ENGINE}"
|
131
|
+
rescue ::LoadError
|
132
|
+
end
|
133
|
+
end
|
134
|
+
ensure
|
135
|
+
$VERBOSE, $DEBUG = verbose, debug
|
136
|
+
end
|
137
|
+
|
138
|
+
module QuickLoader
|
139
|
+
|
140
|
+
@loaded_full_rubygems_library = false
|
141
|
+
|
142
|
+
def self.load_full_rubygems_library
|
143
|
+
if $DEBUG || $VERBOSE
|
144
|
+
$stderr.puts 'warning, loading full rubygems'
|
145
|
+
end
|
146
|
+
return if @loaded_full_rubygems_library
|
147
|
+
|
148
|
+
@loaded_full_rubygems_library = true
|
149
|
+
|
150
|
+
class << Gem
|
151
|
+
undef_method(*Gem::GEM_PRELUDE_METHODS)
|
152
|
+
undef_method :const_missing
|
153
|
+
undef_method :method_missing
|
154
|
+
end
|
155
|
+
|
156
|
+
Kernel.module_eval do
|
157
|
+
undef_method :gem if method_defined? :gem
|
158
|
+
end
|
159
|
+
|
160
|
+
$".delete path_to_full_rubygems_library
|
161
|
+
if $".any? {|path| path =~ Regexp.new('/rubygems.rb$')}
|
162
|
+
raise LoadError, "another rubygems is already loaded from #{path}"
|
163
|
+
end
|
164
|
+
require 'rubygems'
|
165
|
+
begin
|
166
|
+
require 'rubygems.rb.bak' # just in case
|
167
|
+
rescue LoadError
|
168
|
+
# ok
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.fake_rubygems_as_loaded
|
173
|
+
path = path_to_full_rubygems_library
|
174
|
+
$" << path unless $".include?(path)
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.path_to_full_rubygems_library
|
178
|
+
# null rubylibprefix may mean 'you have loaded the other rubygems already somehow...' hmm
|
179
|
+
prefix = (RbConfig::CONFIG["rubylibprefix"] || RbConfig::CONFIG['rubylibdir'].split('/')[0..-2].join('/'))
|
180
|
+
installed_path = File.join(prefix, Gem::ConfigMap[:ruby_version])
|
181
|
+
if $:.include?(installed_path)
|
182
|
+
return File.join(installed_path, 'rubygems.rb')
|
183
|
+
else # e.g., on test-all
|
184
|
+
$:.each do |dir|
|
185
|
+
if File.exist?( path = File.join(dir, 'rubygems.rb') )
|
186
|
+
return path
|
187
|
+
end
|
188
|
+
end
|
189
|
+
raise LoadError, 'rubygems.rb'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
GemPaths = {}
|
194
|
+
GemVersions = {}
|
195
|
+
|
196
|
+
def push_gem_version_on_load_path(gem_name, *version_requirements)
|
197
|
+
if version_requirements.empty?
|
198
|
+
unless GemPaths.has_key?(gem_name) then
|
199
|
+
raise Gem::LoadError, "Could not find RubyGem #{gem_name} (>= 0)\n"
|
200
|
+
end
|
201
|
+
|
202
|
+
# highest version gems already active
|
203
|
+
return false
|
204
|
+
else
|
205
|
+
if version_requirements.length > 1 then
|
206
|
+
QuickLoader.load_full_rubygems_library
|
207
|
+
return gem(gem_name, *version_requirements)
|
208
|
+
end
|
209
|
+
|
210
|
+
requirement, version = version_requirements[0].split
|
211
|
+
requirement.strip!
|
212
|
+
|
213
|
+
if loaded_version = GemVersions[gem_name] then
|
214
|
+
case requirement
|
215
|
+
when ">", ">=" then
|
216
|
+
return false if
|
217
|
+
(loaded_version <=> Gem.integers_for(version)) >= 0
|
218
|
+
when "~>" then
|
219
|
+
required_version = Gem.integers_for version
|
220
|
+
|
221
|
+
return false if loaded_version.first == required_version.first
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
QuickLoader.load_full_rubygems_library
|
226
|
+
gem gem_name, *version_requirements
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def integers_for(gem_version)
|
231
|
+
numbers = gem_version.split(".").collect {|n| n.to_i}
|
232
|
+
numbers.pop while numbers.last == 0
|
233
|
+
numbers << 0 if numbers.empty?
|
234
|
+
numbers
|
235
|
+
end
|
236
|
+
|
237
|
+
def push_all_highest_version_gems_on_load_path
|
238
|
+
Gem.path.each do |path|
|
239
|
+
gems_directory = File.join(path, "gems")
|
240
|
+
|
241
|
+
if File.exist?(gems_directory) then
|
242
|
+
Dir.entries(gems_directory).each do |gem_directory_name|
|
243
|
+
next if gem_directory_name == "." || gem_directory_name == ".."
|
244
|
+
|
245
|
+
next unless gem_name = gem_directory_name[/(.*)-(.*)/, 1]
|
246
|
+
new_version = integers_for($2)
|
247
|
+
current_version = GemVersions[gem_name]
|
248
|
+
|
249
|
+
if !current_version or (current_version <=> new_version) < 0 then
|
250
|
+
GemVersions[gem_name] = new_version
|
251
|
+
GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
require_paths = []
|
258
|
+
|
259
|
+
GemPaths.each_value do |path|
|
260
|
+
if File.exist?(file = File.join(path, ".require_paths")) then
|
261
|
+
paths = File.read(file).split.map do |require_path|
|
262
|
+
File.join path, require_path
|
263
|
+
end
|
264
|
+
|
265
|
+
require_paths.concat paths
|
266
|
+
else
|
267
|
+
require_paths << file if File.exist?(file = File.join(path, "bin"))
|
268
|
+
require_paths << file if File.exist?(file = File.join(path, "lib"))
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# "tag" the first require_path inserted into the $LOAD_PATH to enable
|
273
|
+
# indexing correctly with rubygems proper when it inserts an explicitly
|
274
|
+
# gem version
|
275
|
+
unless require_paths.empty? then
|
276
|
+
require_paths.first.instance_variable_set(:@gem_prelude_index, true)
|
277
|
+
end
|
278
|
+
# gem directories must come after -I and ENV['RUBYLIB']
|
279
|
+
$:[$:.find{|e|e.instance_variable_defined?(:@gem_prelude_index)}||-1,0] = require_paths
|
280
|
+
end
|
281
|
+
|
282
|
+
def const_missing(constant)
|
283
|
+
QuickLoader.load_full_rubygems_library
|
284
|
+
|
285
|
+
if Gem.const_defined?(constant) then
|
286
|
+
Gem.const_get constant
|
287
|
+
else
|
288
|
+
super
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def method_missing(method, *args, &block)
|
293
|
+
QuickLoader.load_full_rubygems_library
|
294
|
+
super unless Gem.respond_to?(method)
|
295
|
+
Gem.send(method, *args, &block)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
extend QuickLoader
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
begin
|
304
|
+
Gem.push_all_highest_version_gems_on_load_path
|
305
|
+
Gem::QuickLoader.fake_rubygems_as_loaded
|
306
|
+
rescue Exception => e
|
307
|
+
puts "Error loading gem paths on load path in gem_prelude"
|
308
|
+
puts e
|
309
|
+
puts e.backtrace.join("\n")
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Gem
|
2
|
+
|
3
|
+
module QuickLoader
|
4
|
+
def bin_path(gem_name, exec_name = null, *version_requirements)
|
5
|
+
unless GemPaths.has_key?(gem_name) then
|
6
|
+
raise Gem::LoadError, "Could not find RubyGem #{gem_name} (>= 0)\n"
|
7
|
+
end
|
8
|
+
|
9
|
+
version_match = false
|
10
|
+
if version_requirements.empty?
|
11
|
+
version_match = true
|
12
|
+
else
|
13
|
+
if version_requirements.length > 1 then
|
14
|
+
version_match = false
|
15
|
+
else
|
16
|
+
|
17
|
+
requirement, version = version_requirements[0].split
|
18
|
+
requirement.strip!
|
19
|
+
|
20
|
+
if loaded_version = GemVersions[gem_name] then
|
21
|
+
case requirement
|
22
|
+
when ">", ">=" then
|
23
|
+
if (loaded_version <=> Gem.integers_for(version)) >= 0
|
24
|
+
version_match = true
|
25
|
+
end
|
26
|
+
when "~>" then
|
27
|
+
required_version = Gem.integers_for version
|
28
|
+
|
29
|
+
if loaded_version.first == required_version.first
|
30
|
+
version_match = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if version_match && exec_name
|
38
|
+
full_path = GemPaths[gem_name] + '/bin/' + exec_name
|
39
|
+
if File.exist? full_path
|
40
|
+
return full_path
|
41
|
+
end
|
42
|
+
end
|
43
|
+
QuickLoader.load_full_rubygems_library
|
44
|
+
bin_path(gem_name, exec_name, *version_requirements)
|
45
|
+
end
|
46
|
+
|
47
|
+
# 1.9.1 doesn't have this...
|
48
|
+
def integers_for(gem_version)
|
49
|
+
numbers = gem_version.split(".").collect {|n| n.to_i}
|
50
|
+
numbers.pop while numbers.last == 0
|
51
|
+
numbers << 0 if numbers.empty?
|
52
|
+
numbers
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
extend QuickLoader
|
58
|
+
|
59
|
+
end
|
data/spec/common.rb
ADDED
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# to test in 1.8.x, make sure to use ruby specname.rb
|
2
|
+
require File.dirname(__FILE__) + "/../lib/faster_rubygems"
|
3
|
+
require 'sane'
|
4
|
+
require 'spec/autorun'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
describe Gem do
|
8
|
+
|
9
|
+
before do
|
10
|
+
ENV['GEM_PATH'] = 'test_dir'
|
11
|
+
@gem_path = 'test_dir/gems/' # wow.
|
12
|
+
FileUtils.rm_rf @gem_path
|
13
|
+
FileUtils.mkdir_p @gem_path
|
14
|
+
end
|
15
|
+
|
16
|
+
context "speeding Gem.bin_path the fake sick way" do
|
17
|
+
|
18
|
+
it "should fake guess the right path instead of loading full rubygems for now" do
|
19
|
+
assert Gem.bin_path('after', 'after', ">= 0") =~ /after.*bin.*after/
|
20
|
+
# should not have loaded full gems...
|
21
|
+
# if this line fails then make sure you are running the spec file like ruby xxx not spec xxx
|
22
|
+
assert !defined?(Gem::Dependency)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context "gem xxx" do
|
28
|
+
it "should allow you to load 'older' gem versions somehow, like maybe cacheing" # lower prio
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faster_rubygems
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 1
|
10
|
+
version: 0.5.1
|
5
11
|
platform: ruby
|
6
12
|
authors: []
|
7
13
|
|
@@ -9,29 +15,71 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-06-21 00:00:00 -06:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: test-unit
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - "="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 25
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 3
|
23
34
|
version: 1.2.3
|
24
|
-
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: test-unit
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
30
42
|
requirements:
|
31
43
|
- - "="
|
32
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 0
|
49
|
+
- 6
|
33
50
|
version: 2.0.6
|
34
|
-
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: after
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - "="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 7
|
65
|
+
- 0
|
66
|
+
version: 0.7.0
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sane
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
type: :development
|
82
|
+
version_requirements: *id004
|
35
83
|
description:
|
36
84
|
email:
|
37
85
|
executables: []
|
@@ -47,15 +95,18 @@ files:
|
|
47
95
|
- examples/require_fast_start.rb
|
48
96
|
- examples/require_rubygems_normal.rb
|
49
97
|
- ext/mkrf_conf.rb
|
50
|
-
-
|
98
|
+
- internalize.rb
|
51
99
|
- lib/faster_rubygems.rb
|
52
|
-
- lib/
|
100
|
+
- lib/faster_rubygems/install.rb
|
53
101
|
- lib/frubygems.rb
|
54
|
-
- lib/
|
102
|
+
- lib/my_defaults.rb
|
103
|
+
- lib/my_gem_prelude.rb
|
104
|
+
- lib/prelude_bin_path.rb
|
105
|
+
- spec/common.rb
|
55
106
|
- spec/files/test_gem.rb
|
56
107
|
- spec/files/test_gem_const.rb
|
57
108
|
- spec/files/test_gem_func.rb
|
58
|
-
- spec/spec.
|
109
|
+
- spec/spec.faster_rubygems_cacheing.rb
|
59
110
|
has_rdoc: true
|
60
111
|
homepage:
|
61
112
|
licenses: []
|
@@ -70,28 +121,35 @@ rdoc_options:
|
|
70
121
|
require_paths:
|
71
122
|
- lib
|
72
123
|
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
73
125
|
requirements:
|
74
126
|
- - ">="
|
75
127
|
- !ruby/object:Gem::Version
|
128
|
+
hash: 3
|
129
|
+
segments:
|
130
|
+
- 0
|
76
131
|
version: "0"
|
77
|
-
version:
|
78
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
79
134
|
requirements:
|
80
135
|
- - ">="
|
81
136
|
- !ruby/object:Gem::Version
|
137
|
+
hash: 3
|
138
|
+
segments:
|
139
|
+
- 0
|
82
140
|
version: "0"
|
83
|
-
version:
|
84
141
|
requirements: []
|
85
142
|
|
86
143
|
rubyforge_project:
|
87
|
-
rubygems_version: 1.3.
|
144
|
+
rubygems_version: 1.3.7
|
88
145
|
signing_key:
|
89
146
|
specification_version: 3
|
90
147
|
summary: faster gem loading
|
91
148
|
test_files:
|
149
|
+
- spec/common.rb
|
92
150
|
- spec/files/test_gem.rb
|
93
151
|
- spec/files/test_gem_const.rb
|
94
152
|
- spec/files/test_gem_func.rb
|
95
|
-
- spec/spec.
|
153
|
+
- spec/spec.faster_rubygems_cacheing.rb
|
96
154
|
- examples/require_fast_start.rb
|
97
155
|
- examples/require_rubygems_normal.rb
|
data/lib/faster_rubygems_lib.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
class FasterRubyGems
|
2
|
-
def self.gem_prelude_paths
|
3
|
-
# note: the RUBY_VERSION[0..2] thing below fails for 1.9...
|
4
|
-
raise 'bad version' if RUBY_VERSION[0..2] > '1.8'
|
5
|
-
require 'rbconfig'
|
6
|
-
|
7
|
-
gem_paths = []
|
8
|
-
# add the default gem path
|
9
|
-
|
10
|
-
gem_paths << Config::CONFIG['libdir'] + '/ruby/gems/' + RUBY_VERSION[0..2] + '/gems'
|
11
|
-
|
12
|
-
# add ~/.gem
|
13
|
-
gem_paths << File.expand_path('~') + '/.gem/ruby/' + RUBY_VERSION[0..2] + '/gems'
|
14
|
-
|
15
|
-
# add ENV['GEM_PATH'] if it exists
|
16
|
-
if ENV['GEM_PATH']
|
17
|
-
gem_paths = ENV['GEM_PATH'].split(File::PATH_SEPARATOR).collect{|path| path + '/gems'}
|
18
|
-
end
|
19
|
-
|
20
|
-
all_gems = []
|
21
|
-
|
22
|
-
for gem_path in gem_paths.flatten do
|
23
|
-
all_gems << Dir.glob(gem_path + '/*')
|
24
|
-
end
|
25
|
-
all_gems.flatten!
|
26
|
-
all_gems = all_gems.sort_by{|gem| gem.split('-')[-1].split('.').map{|n| n.to_i}} # 0.10.0 > 0.9.0 so straight sort won't work for us
|
27
|
-
all_gems.reverse!
|
28
|
-
|
29
|
-
already_loaded_gems = {}
|
30
|
-
|
31
|
-
prelude_paths = []
|
32
|
-
|
33
|
-
for gem in all_gems do
|
34
|
-
|
35
|
-
version = gem.split('-')[-1]
|
36
|
-
if version =~ /\d+\.\d+\.\d+/
|
37
|
-
name = gem.split('-')[0..-2]
|
38
|
-
else
|
39
|
-
gem =~ /(.*)(\d+\.\d+\.\d+).*$/ # like abc-1.2.3-mswin32-60 or what not
|
40
|
-
version = $2
|
41
|
-
name = $1
|
42
|
-
next unless version # a few oddities like rbfind-1.1
|
43
|
-
end
|
44
|
-
|
45
|
-
if(!already_loaded_gems[name])
|
46
|
-
already_loaded_gems[name] = true
|
47
|
-
if File.directory? gem + '/lib'
|
48
|
-
prelude_paths << gem + '/lib'
|
49
|
-
else
|
50
|
-
# unfortunately a few gems load from, say gem/something_not_lib/gemname.rb
|
51
|
-
for dir in Dir.glob(gem + '/*') do
|
52
|
-
if File.directory? dir
|
53
|
-
$: << dir
|
54
|
-
# if anybody wants anything lower than that, let me know
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
prelude_paths
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
data/lib/ubygemsf.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'faster_rubygems'
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'rubygems' if RUBY_VERSION[0..2] < '1.9'
|
2
|
-
require 'sane'
|
3
|
-
require_relative '../lib/faster_rubygems_lib'
|
4
|
-
require 'spec/autorun'
|
5
|
-
require 'fileutils'
|
6
|
-
|
7
|
-
describe FasterRubyGems do
|
8
|
-
|
9
|
-
before do
|
10
|
-
ENV['GEM_PATH'] = 'test_dir'
|
11
|
-
@gem_path = 'test_dir/gems/' # boo
|
12
|
-
FileUtils.rm_rf @gem_path
|
13
|
-
raise 'you dont need to test this on 1.9' if RUBY_VERSION > '1.9'
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should calculate something" do
|
17
|
-
paths = FasterRubyGems.gem_prelude_paths
|
18
|
-
assert paths.length == 0
|
19
|
-
FileUtils.mkdir_p @gem_path + '/abc-0.9.0/lib'
|
20
|
-
paths = FasterRubyGems.gem_prelude_paths
|
21
|
-
assert paths.length == 1
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should calculate 0.10.0 as greater than 0.9.0" do
|
25
|
-
|
26
|
-
FileUtils.mkdir_p @gem_path + '/abc-0.9.0/lib'
|
27
|
-
FileUtils.mkdir_p @gem_path + '/abc-0.10.0/lib'
|
28
|
-
paths = FasterRubyGems.gem_prelude_paths
|
29
|
-
assert( (paths.grep /abc-0.10.0/).length > 0)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should find highest version of normal numbered gems" do
|
33
|
-
FileUtils.mkdir_p @gem_path + '/abc-0.8.0/lib'
|
34
|
-
FileUtils.mkdir_p @gem_path + '/abc-0.9.0/lib'
|
35
|
-
paths = FasterRubyGems.gem_prelude_paths
|
36
|
-
assert( (paths.grep /abc-0.9.0/).length > 0)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "with multiple paths should find all files"
|
40
|
-
|
41
|
-
it "should respect file::separator"
|
42
|
-
|
43
|
-
|
44
|
-
def ruby lib
|
45
|
-
assert system(OS.ruby_bin + ' ' + lib)
|
46
|
-
assert system(OS.ruby_bin + ' ' + lib)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should load full rubygems on gem xxx" do
|
50
|
-
ruby('files/test_gem.rb')
|
51
|
-
ruby('files/test_gem_const.rb')
|
52
|
-
ruby('files/test_gem_func.rb')
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|