faster_rubygems 0.2.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|