rubygems-update 1.8.30 → 2.0.0.preview2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +6 -6
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +3 -0
- data/.autotest +6 -3
- data/History.txt +137 -63
- data/LICENSE.txt +1 -5
- data/Manifest.txt +69 -32
- data/README.rdoc +11 -9
- data/Rakefile +24 -38
- data/bin/gem +0 -9
- data/bin/update_rubygems +1 -0
- data/lib/rubygems.rb +193 -405
- data/lib/rubygems/available_set.rb +95 -0
- data/lib/rubygems/command.rb +88 -45
- data/lib/rubygems/command_manager.rb +67 -40
- data/lib/rubygems/commands/build_command.rb +5 -23
- data/lib/rubygems/commands/cert_command.rb +199 -57
- data/lib/rubygems/commands/check_command.rb +14 -39
- data/lib/rubygems/commands/cleanup_command.rb +9 -1
- data/lib/rubygems/commands/contents_command.rb +30 -12
- data/lib/rubygems/commands/dependency_command.rb +3 -8
- data/lib/rubygems/commands/environment_command.rb +13 -8
- data/lib/rubygems/commands/fetch_command.rb +3 -16
- data/lib/rubygems/commands/generate_index_command.rb +7 -47
- data/lib/rubygems/commands/help_command.rb +1 -1
- data/lib/rubygems/commands/install_command.rb +69 -36
- data/lib/rubygems/commands/list_command.rb +6 -4
- data/lib/rubygems/commands/lock_command.rb +1 -1
- data/lib/rubygems/commands/mirror_command.rb +17 -0
- data/lib/rubygems/commands/outdated_command.rb +6 -3
- data/lib/rubygems/commands/owner_command.rb +13 -5
- data/lib/rubygems/commands/pristine_command.rb +19 -4
- data/lib/rubygems/commands/push_command.rb +12 -1
- data/lib/rubygems/commands/query_command.rb +43 -27
- data/lib/rubygems/commands/rdoc_command.rb +23 -28
- data/lib/rubygems/commands/search_command.rb +4 -18
- data/lib/rubygems/commands/server_command.rb +1 -1
- data/lib/rubygems/commands/setup_command.rb +124 -38
- data/lib/rubygems/commands/sources_command.rb +16 -16
- data/lib/rubygems/commands/specification_command.rb +11 -13
- data/lib/rubygems/commands/uninstall_command.rb +24 -7
- data/lib/rubygems/commands/unpack_command.rb +7 -3
- data/lib/rubygems/commands/update_command.rb +22 -36
- data/lib/rubygems/commands/yank_command.rb +98 -0
- data/lib/rubygems/compatibility.rb +51 -0
- data/lib/rubygems/config_file.rb +82 -54
- data/lib/rubygems/core_ext/kernel_gem.rb +53 -0
- data/lib/rubygems/core_ext/kernel_require.rb +119 -0
- data/lib/rubygems/defaults.rb +10 -21
- data/lib/rubygems/dependency.rb +61 -10
- data/lib/rubygems/dependency_installer.rb +157 -69
- data/lib/rubygems/dependency_list.rb +11 -19
- data/lib/rubygems/dependency_resolver.rb +562 -0
- data/lib/rubygems/deprecate.rb +40 -40
- data/lib/rubygems/errors.rb +77 -24
- data/lib/rubygems/exceptions.rb +25 -7
- data/lib/rubygems/ext/builder.rb +20 -23
- data/lib/rubygems/ext/configure_builder.rb +2 -2
- data/lib/rubygems/ext/ext_conf_builder.rb +5 -45
- data/lib/rubygems/ext/rake_builder.rb +2 -2
- data/lib/rubygems/gem_runner.rb +3 -16
- data/lib/rubygems/gemcutter_utilities.rb +22 -7
- data/lib/rubygems/indexer.rb +6 -159
- data/lib/rubygems/install_message.rb +12 -0
- data/lib/rubygems/install_update_options.rb +56 -18
- data/lib/rubygems/installer.rb +244 -134
- data/lib/rubygems/installer_test_case.rb +71 -19
- data/lib/rubygems/mock_gem_ui.rb +17 -0
- data/lib/rubygems/name_tuple.rb +110 -0
- data/lib/rubygems/package.rb +514 -43
- data/lib/rubygems/package/digest_io.rb +64 -0
- data/lib/rubygems/package/old.rb +147 -0
- data/lib/rubygems/package/tar_header.rb +18 -55
- data/lib/rubygems/package/tar_reader.rb +20 -3
- data/lib/rubygems/package/tar_writer.rb +63 -7
- data/lib/rubygems/package_task.rb +3 -4
- data/lib/rubygems/path_support.rb +14 -7
- data/lib/rubygems/platform.rb +19 -26
- data/lib/rubygems/rdoc.rb +316 -0
- data/lib/rubygems/remote_fetcher.rb +117 -54
- data/lib/rubygems/request_set.rb +182 -0
- data/lib/rubygems/requirement.rb +63 -26
- data/lib/rubygems/security.rb +295 -555
- data/lib/rubygems/security/policies.rb +115 -0
- data/lib/rubygems/security/policy.rb +227 -0
- data/lib/rubygems/security/signer.rb +136 -0
- data/lib/rubygems/security/trust_dir.rb +104 -0
- data/lib/rubygems/server.rb +45 -55
- data/lib/rubygems/source.rb +144 -0
- data/lib/rubygems/source_list.rb +87 -0
- data/lib/rubygems/source_local.rb +92 -0
- data/lib/rubygems/source_specific_file.rb +28 -0
- data/lib/rubygems/spec_fetcher.rb +116 -184
- data/lib/rubygems/specification.rb +731 -335
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
- data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
- data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
- data/lib/rubygems/syck_hack.rb +2 -0
- data/lib/rubygems/test_case.rb +199 -109
- data/lib/rubygems/test_utilities.rb +25 -5
- data/lib/rubygems/uninstaller.rb +62 -20
- data/lib/rubygems/user_interaction.rb +10 -0
- data/lib/rubygems/validator.rb +33 -40
- data/lib/rubygems/version.rb +19 -8
- data/setup.rb +8 -1
- data/test/rubygems/alternate_cert.pem +9 -0
- data/test/rubygems/alternate_cert_32.pem +9 -0
- data/test/rubygems/alternate_key.pem +9 -0
- data/test/rubygems/bad_rake.rb +1 -0
- data/test/rubygems/child_cert.pem +9 -0
- data/test/rubygems/child_cert_32.pem +9 -0
- data/test/rubygems/child_key.pem +9 -0
- data/test/rubygems/data/null-type.gemspec.rz +0 -0
- data/test/rubygems/expired_cert.pem +9 -0
- data/test/rubygems/future_cert.pem +9 -0
- data/test/rubygems/future_cert_32.pem +9 -0
- data/test/rubygems/good_rake.rb +1 -0
- data/test/rubygems/grandchild_cert.pem +9 -0
- data/test/rubygems/grandchild_cert_32.pem +9 -0
- data/test/rubygems/grandchild_key.pem +9 -0
- data/test/rubygems/invalid_issuer_cert.pem +9 -0
- data/test/rubygems/invalid_issuer_cert_32.pem +9 -0
- data/test/rubygems/invalid_key.pem +9 -0
- data/test/rubygems/invalid_signer_cert.pem +9 -0
- data/test/rubygems/invalid_signer_cert_32.pem +9 -0
- data/test/rubygems/invalidchild_cert.pem +9 -0
- data/test/rubygems/invalidchild_cert_32.pem +9 -0
- data/test/rubygems/invalidchild_key.pem +9 -0
- data/test/rubygems/plugin/exception/rubygems_plugin.rb +1 -1
- data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +1 -1
- data/test/rubygems/private_key.pem +7 -25
- data/test/rubygems/public_cert.pem +8 -18
- data/test/rubygems/public_cert_32.pem +10 -0
- data/test/rubygems/public_key.pem +4 -0
- data/test/rubygems/rubygems/commands/crash_command.rb +1 -1
- data/test/rubygems/test_config.rb +4 -6
- data/test/rubygems/test_deprecate.rb +76 -0
- data/test/rubygems/test_gem.rb +318 -83
- data/test/rubygems/test_gem_available_set.rb +106 -0
- data/test/rubygems/test_gem_command.rb +10 -0
- data/test/rubygems/test_gem_command_manager.rb +55 -9
- data/test/rubygems/test_gem_commands_build_command.rb +11 -19
- data/test/rubygems/test_gem_commands_cert_command.rb +441 -42
- data/test/rubygems/test_gem_commands_cleanup_command.rb +29 -1
- data/test/rubygems/test_gem_commands_contents_command.rb +23 -0
- data/test/rubygems/test_gem_commands_dependency_command.rb +5 -0
- data/test/rubygems/test_gem_commands_fetch_command.rb +19 -20
- data/test/rubygems/test_gem_commands_generate_index_command.rb +2 -83
- data/test/rubygems/test_gem_commands_help_command.rb +2 -1
- data/test/rubygems/test_gem_commands_install_command.rb +647 -48
- data/test/rubygems/test_gem_commands_mirror.rb +32 -0
- data/test/rubygems/test_gem_commands_owner_command.rb +4 -8
- data/test/rubygems/test_gem_commands_pristine_command.rb +99 -4
- data/test/rubygems/test_gem_commands_push_command.rb +62 -8
- data/test/rubygems/test_gem_commands_query_command.rb +51 -0
- data/test/rubygems/test_gem_commands_search_command.rb +25 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +45 -0
- data/test/rubygems/test_gem_commands_sources_command.rb +21 -6
- data/test/rubygems/test_gem_commands_specification_command.rb +33 -1
- data/test/rubygems/test_gem_commands_uninstall_command.rb +91 -31
- data/test/rubygems/test_gem_commands_unpack_command.rb +3 -3
- data/test/rubygems/test_gem_commands_update_command.rb +56 -38
- data/test/rubygems/test_gem_commands_which_command.rb +4 -4
- data/test/rubygems/test_gem_commands_yank_command.rb +97 -0
- data/test/rubygems/test_gem_config_file.rb +66 -21
- data/test/rubygems/test_gem_dependency.rb +46 -0
- data/test/rubygems/test_gem_dependency_installer.rb +228 -18
- data/test/rubygems/test_gem_dependency_list.rb +0 -9
- data/test/rubygems/test_gem_dependency_resolver.rb +327 -0
- data/test/rubygems/test_gem_ext_configure_builder.rb +4 -4
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +21 -49
- data/test/rubygems/test_gem_ext_rake_builder.rb +13 -13
- data/test/rubygems/test_gem_gem_runner.rb +27 -5
- data/test/rubygems/test_gem_gemcutter_utilities.rb +19 -0
- data/test/rubygems/test_gem_indexer.rb +14 -227
- data/test/rubygems/test_gem_install_update_options.rb +83 -3
- data/test/rubygems/test_gem_installer.rb +211 -236
- data/test/rubygems/test_gem_local_remote_options.rb +8 -2
- data/test/rubygems/test_gem_name_tuple.rb +15 -0
- data/test/rubygems/test_gem_package.rb +547 -0
- data/test/rubygems/test_gem_package_old.rb +37 -0
- data/test/rubygems/test_gem_package_tar_reader.rb +32 -0
- data/test/rubygems/test_gem_package_tar_writer.rb +84 -1
- data/test/rubygems/test_gem_path_support.rb +4 -30
- data/test/rubygems/test_gem_platform.rb +3 -6
- data/test/rubygems/test_gem_rdoc.rb +245 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +51 -5
- data/test/rubygems/test_gem_request_set.rb +70 -0
- data/test/rubygems/test_gem_requirement.rb +53 -24
- data/test/rubygems/test_gem_security.rb +189 -43
- data/test/rubygems/test_gem_security_policy.rb +376 -0
- data/test/rubygems/test_gem_security_signer.rb +184 -0
- data/test/rubygems/test_gem_security_trust_dir.rb +94 -0
- data/test/rubygems/test_gem_server.rb +31 -36
- data/test/rubygems/test_gem_silent_ui.rb +2 -2
- data/test/rubygems/test_gem_source.rb +188 -0
- data/test/rubygems/test_gem_source_list.rb +87 -0
- data/test/rubygems/test_gem_source_local.rb +83 -0
- data/test/rubygems/test_gem_source_specific_file.rb +33 -0
- data/test/rubygems/test_gem_spec_fetcher.rb +91 -255
- data/test/rubygems/test_gem_specification.rb +293 -39
- data/test/rubygems/test_gem_uninstaller.rb +136 -13
- data/test/rubygems/test_gem_validator.rb +14 -41
- data/test/rubygems/test_gem_version.rb +15 -21
- data/test/rubygems/test_require.rb +193 -0
- data/test/rubygems/wrong_key_cert.pem +9 -0
- data/test/rubygems/wrong_key_cert_32.pem +9 -0
- metadata +171 -83
- metadata.gz.sig +1 -0
- data/CVE-2013-4287.txt +0 -36
- data/CVE-2013-4363.txt +0 -45
- data/ci_build.sh +0 -27
- data/cruise_config.rb +0 -32
- data/lib/rbconfig/datadir.rb +0 -13
- data/lib/rubygems/builder.rb +0 -99
- data/lib/rubygems/custom_require.rb +0 -69
- data/lib/rubygems/doc_manager.rb +0 -243
- data/lib/rubygems/format.rb +0 -82
- data/lib/rubygems/gem_openssl.rb +0 -90
- data/lib/rubygems/gem_path_searcher.rb +0 -172
- data/lib/rubygems/old_format.rb +0 -153
- data/lib/rubygems/package/f_sync_dir.rb +0 -23
- data/lib/rubygems/package/tar_input.rb +0 -234
- data/lib/rubygems/package/tar_output.rb +0 -146
- data/lib/rubygems/require_paths_builder.rb +0 -18
- data/lib/rubygems/source_index.rb +0 -406
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
- data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
- data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
- data/lib/rubygems/ssl_certs/GeoTrustGlobalCA.pem +0 -20
- data/test/rubygems/test_bundled_ca.rb +0 -59
- data/test/rubygems/test_gem_builder.rb +0 -44
- data/test/rubygems/test_gem_doc_manager.rb +0 -32
- data/test/rubygems/test_gem_ext_builder.rb +0 -58
- data/test/rubygems/test_gem_format.rb +0 -88
- data/test/rubygems/test_gem_gem_path_searcher.rb +0 -94
- data/test/rubygems/test_gem_package_tar_input.rb +0 -129
- data/test/rubygems/test_gem_package_tar_output.rb +0 -101
- data/test/rubygems/test_gem_source_index.rb +0 -250
- data/util/update_bundled_ca_certificates.rb +0 -103
data/lib/rubygems/defaults.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Gem
|
2
|
-
|
3
|
-
# TODO: move this whole file back into rubygems.rb
|
2
|
+
DEFAULT_HOST = "https://rubygems.org"
|
4
3
|
|
5
4
|
@post_install_hooks ||= []
|
5
|
+
@done_installing_hooks ||= []
|
6
6
|
@post_uninstall_hooks ||= []
|
7
7
|
@pre_uninstall_hooks ||= []
|
8
8
|
@pre_install_hooks ||= []
|
@@ -57,11 +57,18 @@ module Gem
|
|
57
57
|
File.join Gem.user_home, '.gem', ruby_engine, ConfigMap[:ruby_version]
|
58
58
|
end
|
59
59
|
|
60
|
+
##
|
61
|
+
# How String Gem paths should be split. Overridable for esoteric platforms.
|
62
|
+
|
63
|
+
def self.path_separator
|
64
|
+
File::PATH_SEPARATOR
|
65
|
+
end
|
66
|
+
|
60
67
|
##
|
61
68
|
# Default gem load path
|
62
69
|
|
63
70
|
def self.default_path
|
64
|
-
if File.exist?
|
71
|
+
if Gem.user_home && File.exist?(Gem.user_home) then
|
65
72
|
[user_dir, default_dir]
|
66
73
|
else
|
67
74
|
[default_dir]
|
@@ -93,24 +100,6 @@ module Gem
|
|
93
100
|
end
|
94
101
|
end
|
95
102
|
|
96
|
-
##
|
97
|
-
# The default system-wide source info cache directory
|
98
|
-
|
99
|
-
def self.default_system_source_cache_dir
|
100
|
-
File.join(Gem.dir, 'source_cache')
|
101
|
-
end
|
102
|
-
|
103
|
-
##
|
104
|
-
# The default user-specific source info cache directory
|
105
|
-
|
106
|
-
def self.default_user_source_cache_dir
|
107
|
-
#
|
108
|
-
# NOTE Probably an argument for moving this to per-ruby supported dirs like
|
109
|
-
# user_dir
|
110
|
-
#
|
111
|
-
File.join(Gem.user_home, '.gem', 'source_cache')
|
112
|
-
end
|
113
|
-
|
114
103
|
##
|
115
104
|
# A wrapper around RUBY_ENGINE const that may not be defined
|
116
105
|
|
data/lib/rubygems/dependency.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require "rubygems/requirement"
|
2
|
-
|
3
1
|
##
|
4
2
|
# The Dependency class holds a Gem name and a Gem::Requirement.
|
5
3
|
|
4
|
+
require "rubygems/requirement"
|
5
|
+
|
6
6
|
class Gem::Dependency
|
7
7
|
|
8
8
|
##
|
@@ -11,6 +11,9 @@ class Gem::Dependency
|
|
11
11
|
# When this list is updated, be sure to change
|
12
12
|
# Gem::Specification::CURRENT_SPECIFICATION_VERSION as well.
|
13
13
|
|
14
|
+
# REFACTOR: This type of constant, TYPES, indicates we might want
|
15
|
+
# two classes, used via inheretance or duck typing.
|
16
|
+
|
14
17
|
TYPES = [
|
15
18
|
:development,
|
16
19
|
:runtime,
|
@@ -32,18 +35,23 @@ class Gem::Dependency
|
|
32
35
|
# <tt>:runtime</tt>.
|
33
36
|
|
34
37
|
def initialize name, *requirements
|
35
|
-
|
38
|
+
case name
|
39
|
+
when String then # ok
|
40
|
+
when Regexp then
|
36
41
|
msg = ["NOTE: Dependency.new w/ a regexp is deprecated.",
|
37
42
|
"Dependency.new called from #{Gem.location_of_caller.join(":")}"]
|
38
43
|
warn msg.join("\n") unless Gem::Deprecate.skip
|
44
|
+
else
|
45
|
+
raise ArgumentError,
|
46
|
+
"dependency name must be a String, was #{name.inspect}"
|
39
47
|
end
|
40
48
|
|
41
49
|
type = Symbol === requirements.last ? requirements.pop : :runtime
|
42
50
|
requirements = requirements.first if 1 == requirements.length # unpack
|
43
51
|
|
44
52
|
unless TYPES.include? type
|
45
|
-
raise ArgumentError, "Valid types are #{TYPES.inspect}, "
|
46
|
-
|
53
|
+
raise ArgumentError, "Valid types are #{TYPES.inspect}, " +
|
54
|
+
"not #{type.inspect}"
|
47
55
|
end
|
48
56
|
|
49
57
|
@name = name
|
@@ -66,8 +74,13 @@ class Gem::Dependency
|
|
66
74
|
end
|
67
75
|
|
68
76
|
def inspect # :nodoc:
|
69
|
-
|
70
|
-
|
77
|
+
if @prerelease
|
78
|
+
"<%s type=%p name=%p requirements=%p prerelease=ok>" %
|
79
|
+
[self.class, self.type, self.name, requirement.to_s]
|
80
|
+
else
|
81
|
+
"<%s type=%p name=%p requirements=%p>" %
|
82
|
+
[self.class, self.type, self.name, requirement.to_s]
|
83
|
+
end
|
71
84
|
end
|
72
85
|
|
73
86
|
##
|
@@ -77,6 +90,14 @@ class Gem::Dependency
|
|
77
90
|
@prerelease || requirement.prerelease?
|
78
91
|
end
|
79
92
|
|
93
|
+
##
|
94
|
+
# Is this dependency simply asking for the latest version
|
95
|
+
# of a gem?
|
96
|
+
|
97
|
+
def latest_version?
|
98
|
+
@requirement.none?
|
99
|
+
end
|
100
|
+
|
80
101
|
def pretty_print q # :nodoc:
|
81
102
|
q.group 1, 'Gem::Dependency.new(', ')' do
|
82
103
|
q.pp name
|
@@ -113,6 +134,8 @@ class Gem::Dependency
|
|
113
134
|
# Children, define explicit marshal and unmarshal behavior for
|
114
135
|
# public classes. Marshal formats are part of your public API.
|
115
136
|
|
137
|
+
# REFACTOR: See above
|
138
|
+
|
116
139
|
if defined?(@version_requirement) && @version_requirement
|
117
140
|
version = @version_requirement.instance_variable_get :@version
|
118
141
|
@version_requirement = nil
|
@@ -122,6 +145,7 @@ class Gem::Dependency
|
|
122
145
|
@requirement = @version_requirements if defined?(@version_requirements)
|
123
146
|
end
|
124
147
|
|
148
|
+
# DOC: this method needs documentation or :nodoc''d
|
125
149
|
def requirements_list
|
126
150
|
requirement.as_list
|
127
151
|
end
|
@@ -179,13 +203,24 @@ class Gem::Dependency
|
|
179
203
|
requirement.satisfied_by? version
|
180
204
|
end
|
181
205
|
|
182
|
-
|
206
|
+
# DOC: this method needs either documented or :nodoc'd
|
207
|
+
|
208
|
+
def match? obj, version=nil
|
209
|
+
if !version
|
210
|
+
name = obj.name
|
211
|
+
version = obj.version
|
212
|
+
else
|
213
|
+
name = obj
|
214
|
+
end
|
215
|
+
|
183
216
|
return false unless self.name === name
|
184
217
|
return true if requirement.none?
|
185
218
|
|
186
219
|
requirement.satisfied_by? Gem::Version.new(version)
|
187
220
|
end
|
188
221
|
|
222
|
+
# DOC: this method needs either documented or :nodoc'd
|
223
|
+
|
189
224
|
def matches_spec? spec
|
190
225
|
return false unless name === spec.name
|
191
226
|
return true if requirement.none?
|
@@ -212,6 +247,8 @@ class Gem::Dependency
|
|
212
247
|
self.class.new name, self_req.as_list.concat(other_req.as_list)
|
213
248
|
end
|
214
249
|
|
250
|
+
# DOC: this method needs either documented or :nodoc'd
|
251
|
+
|
215
252
|
def matching_specs platform_only = false
|
216
253
|
matches = Gem::Specification.find_all { |spec|
|
217
254
|
self.name === spec.name and # TODO: == instead of ===
|
@@ -234,14 +271,26 @@ class Gem::Dependency
|
|
234
271
|
@requirement.specific?
|
235
272
|
end
|
236
273
|
|
274
|
+
# DOC: this method needs either documented or :nodoc'd
|
275
|
+
|
237
276
|
def to_specs
|
238
277
|
matches = matching_specs true
|
239
278
|
|
240
279
|
# TODO: check Gem.activated_spec[self.name] in case matches falls outside
|
241
280
|
|
242
281
|
if matches.empty? then
|
243
|
-
specs = Gem::Specification.
|
244
|
-
|
282
|
+
specs = Gem::Specification.find_all { |s|
|
283
|
+
s.name == name
|
284
|
+
}.map { |x| x.full_name }
|
285
|
+
|
286
|
+
if specs.empty?
|
287
|
+
total = Gem::Specification.to_a.size
|
288
|
+
error = Gem::LoadError.new \
|
289
|
+
"Could not find '#{name}' (#{requirement}) among #{total} total gem(s)"
|
290
|
+
else
|
291
|
+
error = Gem::LoadError.new \
|
292
|
+
"Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]"
|
293
|
+
end
|
245
294
|
error.name = self.name
|
246
295
|
error.requirement = self.requirement
|
247
296
|
raise error
|
@@ -252,6 +301,8 @@ class Gem::Dependency
|
|
252
301
|
matches
|
253
302
|
end
|
254
303
|
|
304
|
+
# DOC: this method needs either documented or :nodoc'd
|
305
|
+
|
255
306
|
def to_spec
|
256
307
|
matches = self.to_specs
|
257
308
|
|
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rubygems/dependency_list'
|
3
|
+
require 'rubygems/package'
|
3
4
|
require 'rubygems/installer'
|
4
5
|
require 'rubygems/spec_fetcher'
|
5
6
|
require 'rubygems/user_interaction'
|
7
|
+
require 'rubygems/source_local'
|
8
|
+
require 'rubygems/source_specific_file'
|
9
|
+
require 'rubygems/available_set'
|
6
10
|
|
7
11
|
##
|
8
12
|
# Installs a gem along with all its dependencies from local and remote gems.
|
@@ -14,8 +18,14 @@ class Gem::DependencyInstaller
|
|
14
18
|
attr_reader :gems_to_install
|
15
19
|
attr_reader :installed_gems
|
16
20
|
|
21
|
+
##
|
22
|
+
# Documentation types. For use by the Gem.done_installing hook
|
23
|
+
|
24
|
+
attr_reader :document
|
25
|
+
|
17
26
|
DEFAULT_OPTIONS = {
|
18
27
|
:env_shebang => false,
|
28
|
+
:document => %w[ri],
|
19
29
|
:domain => :both, # HACK dup
|
20
30
|
:force => false,
|
21
31
|
:format_executable => false, # HACK dup
|
@@ -23,7 +33,8 @@ class Gem::DependencyInstaller
|
|
23
33
|
:prerelease => false,
|
24
34
|
:security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low?
|
25
35
|
:wrappers => true,
|
26
|
-
|
36
|
+
:build_docs_in_background => false,
|
37
|
+
}.freeze
|
27
38
|
|
28
39
|
##
|
29
40
|
# Creates a new installer instance.
|
@@ -47,6 +58,7 @@ class Gem::DependencyInstaller
|
|
47
58
|
if options[:install_dir] then
|
48
59
|
@gem_home = options[:install_dir]
|
49
60
|
|
61
|
+
# HACK shouldn't change the global settings
|
50
62
|
Gem::Specification.dirs = @gem_home
|
51
63
|
Gem.ensure_gem_subdirectories @gem_home
|
52
64
|
options[:install_dir] = @gem_home # FIX: because we suck and reuse below
|
@@ -55,7 +67,9 @@ class Gem::DependencyInstaller
|
|
55
67
|
options = DEFAULT_OPTIONS.merge options
|
56
68
|
|
57
69
|
@bin_dir = options[:bin_dir]
|
70
|
+
@dev_shallow = options[:dev_shallow]
|
58
71
|
@development = options[:development]
|
72
|
+
@document = options[:document]
|
59
73
|
@domain = options[:domain]
|
60
74
|
@env_shebang = options[:env_shebang]
|
61
75
|
@force = options[:force]
|
@@ -65,8 +79,14 @@ class Gem::DependencyInstaller
|
|
65
79
|
@security_policy = options[:security_policy]
|
66
80
|
@user_install = options[:user_install]
|
67
81
|
@wrappers = options[:wrappers]
|
82
|
+
@build_docs_in_background = options[:build_docs_in_background]
|
83
|
+
|
84
|
+
# Indicates that we should not try to update any deps unless
|
85
|
+
# we absolutely must.
|
86
|
+
@minimal_deps = options[:minimal_deps]
|
68
87
|
|
69
88
|
@installed_gems = []
|
89
|
+
@toplevel_specs = nil
|
70
90
|
|
71
91
|
@install_dir = options[:install_dir] || Gem.dir
|
72
92
|
@cache_dir = options[:cache_dir] || @install_dir
|
@@ -76,6 +96,24 @@ class Gem::DependencyInstaller
|
|
76
96
|
@errors = nil
|
77
97
|
end
|
78
98
|
|
99
|
+
attr_reader :errors
|
100
|
+
|
101
|
+
##
|
102
|
+
# Indicated, based on the requested domain, if local
|
103
|
+
# gems should be considered.
|
104
|
+
|
105
|
+
def consider_local?
|
106
|
+
@domain == :both or @domain == :local
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Indicated, based on the requested domain, if remote
|
111
|
+
# gems should be considered.
|
112
|
+
|
113
|
+
def consider_remote?
|
114
|
+
@domain == :both or @domain == :remote
|
115
|
+
end
|
116
|
+
|
79
117
|
##
|
80
118
|
# Returns a list of pairs of gemspecs and source_uris that match
|
81
119
|
# Gem::Dependency +dep+ from both local (Dir.pwd) and remote (Gem.sources)
|
@@ -83,35 +121,34 @@ class Gem::DependencyInstaller
|
|
83
121
|
# local gems preferred over remote gems.
|
84
122
|
|
85
123
|
def find_gems_with_sources(dep)
|
86
|
-
|
87
|
-
|
88
|
-
|
124
|
+
set = Gem::AvailableSet.new
|
125
|
+
|
126
|
+
if consider_local?
|
127
|
+
sl = Gem::Source::Local.new
|
89
128
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
129
|
+
if spec = sl.find_gem(dep.name)
|
130
|
+
if dep.matches_spec? spec
|
131
|
+
set.add spec, sl
|
132
|
+
end
|
94
133
|
end
|
95
134
|
end
|
96
135
|
|
97
|
-
if
|
136
|
+
if consider_remote?
|
98
137
|
begin
|
99
|
-
|
100
|
-
requirements = dep.requirement.requirements.map do |req, ver|
|
101
|
-
req
|
102
|
-
end
|
103
|
-
|
104
|
-
all = !dep.prerelease? &&
|
105
|
-
# we only need latest if there's one requirement and it is
|
106
|
-
# guaranteed to match the newest specs
|
107
|
-
(requirements.length > 1 or
|
108
|
-
(requirements.first != ">=" and requirements.first != ">"))
|
138
|
+
found, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
|
109
139
|
|
110
|
-
|
140
|
+
if @errors
|
141
|
+
@errors += errors
|
142
|
+
else
|
143
|
+
@errors = errors
|
144
|
+
end
|
111
145
|
|
112
|
-
|
146
|
+
set << found
|
113
147
|
|
114
148
|
rescue Gem::RemoteFetcher::FetchError => e
|
149
|
+
# FIX if there is a problem talking to the network, we either need to always tell
|
150
|
+
# the user (no really_verbose) or fail hard, not silently tell them that we just
|
151
|
+
# couldn't find their requested gem.
|
115
152
|
if Gem.configuration.really_verbose then
|
116
153
|
say "Error fetching remote data:\t\t#{e.message}"
|
117
154
|
say "Falling back to local-only install"
|
@@ -120,9 +157,7 @@ class Gem::DependencyInstaller
|
|
120
157
|
end
|
121
158
|
end
|
122
159
|
|
123
|
-
|
124
|
-
[gem, source =~ /^http:\/\// ? 0 : 1] # local gems win
|
125
|
-
end
|
160
|
+
set
|
126
161
|
end
|
127
162
|
|
128
163
|
##
|
@@ -130,17 +165,22 @@ class Gem::DependencyInstaller
|
|
130
165
|
# remote sources unless the ignore_dependencies was given.
|
131
166
|
|
132
167
|
def gather_dependencies
|
133
|
-
specs = @
|
168
|
+
specs = @available.all_specs
|
134
169
|
|
135
170
|
# these gems were listed by the user, always install them
|
136
171
|
keep_names = specs.map { |spec| spec.full_name }
|
137
172
|
|
173
|
+
if @dev_shallow
|
174
|
+
@toplevel_specs = keep_names
|
175
|
+
end
|
176
|
+
|
138
177
|
dependency_list = Gem::DependencyList.new @development
|
139
178
|
dependency_list.add(*specs)
|
140
179
|
to_do = specs.dup
|
141
|
-
|
142
180
|
add_found_dependencies to_do, dependency_list unless @ignore_dependencies
|
143
181
|
|
182
|
+
# REFACTOR maybe abstract away using Gem::Specification.include? so
|
183
|
+
# that this isn't dependent only on the currently installed gems
|
144
184
|
dependency_list.specs.reject! { |spec|
|
145
185
|
not keep_names.include?(spec.full_name) and
|
146
186
|
Gem::Specification.include?(spec)
|
@@ -162,32 +202,43 @@ class Gem::DependencyInstaller
|
|
162
202
|
|
163
203
|
until to_do.empty? do
|
164
204
|
spec = to_do.shift
|
205
|
+
|
206
|
+
# HACK why is spec nil?
|
165
207
|
next if spec.nil? or seen[spec.name]
|
166
208
|
seen[spec.name] = true
|
167
209
|
|
168
210
|
deps = spec.runtime_dependencies
|
169
|
-
|
211
|
+
|
212
|
+
if @development
|
213
|
+
if @dev_shallow
|
214
|
+
if @toplevel_specs.include? spec.full_name
|
215
|
+
deps |= spec.development_dependencies
|
216
|
+
end
|
217
|
+
else
|
218
|
+
deps |= spec.development_dependencies
|
219
|
+
end
|
220
|
+
end
|
170
221
|
|
171
222
|
deps.each do |dep|
|
172
223
|
dependencies[dep.name] = dependencies[dep.name].merge dep
|
173
224
|
|
174
|
-
|
225
|
+
if @minimal_deps
|
226
|
+
next if Gem::Specification.any? do |installed_spec|
|
227
|
+
dep.name == installed_spec.name and
|
228
|
+
dep.requirement.satisfied_by? installed_spec.version
|
229
|
+
end
|
230
|
+
end
|
175
231
|
|
176
|
-
results
|
177
|
-
to_do.push dep_spec
|
232
|
+
results = find_gems_with_sources(dep)
|
178
233
|
|
179
|
-
|
180
|
-
|
181
|
-
dep.name == installed_spec.name and
|
182
|
-
dep.requirement.satisfied_by? installed_spec.version
|
183
|
-
end
|
234
|
+
results.sorted.each do |t|
|
235
|
+
to_do.push t.spec
|
184
236
|
end
|
185
237
|
|
186
|
-
results.
|
187
|
-
@specs_and_sources << [dep_spec, source_uri]
|
238
|
+
results.remove_installed! dep
|
188
239
|
|
189
|
-
|
190
|
-
|
240
|
+
@available << results
|
241
|
+
results.inject_into_list dependency_list
|
191
242
|
end
|
192
243
|
end
|
193
244
|
|
@@ -202,42 +253,36 @@ class Gem::DependencyInstaller
|
|
202
253
|
def find_spec_by_name_and_version(gem_name,
|
203
254
|
version = Gem::Requirement.default,
|
204
255
|
prerelease = false)
|
205
|
-
spec_and_source = nil
|
206
256
|
|
207
|
-
|
208
|
-
gem_name.gsub File::ALT_SEPARATOR, File::SEPARATOR
|
209
|
-
else
|
210
|
-
gem_name
|
211
|
-
end
|
257
|
+
set = Gem::AvailableSet.new
|
212
258
|
|
213
|
-
|
259
|
+
if consider_local?
|
260
|
+
if File.exists? gem_name
|
261
|
+
src = Gem::Source::SpecificFile.new(gem_name)
|
262
|
+
set.add src.spec, src
|
263
|
+
else
|
264
|
+
local = Gem::Source::Local.new
|
214
265
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
spec = Gem::Format.from_file_by_path(gem_file).spec
|
219
|
-
spec_and_source = [spec, gem_file]
|
220
|
-
break
|
221
|
-
rescue SystemCallError, Gem::Package::FormatError
|
266
|
+
if s = local.find_gem(gem_name, version)
|
267
|
+
set.add s, local
|
268
|
+
end
|
222
269
|
end
|
223
270
|
end
|
224
271
|
|
225
|
-
|
272
|
+
if set.empty?
|
226
273
|
dep = Gem::Dependency.new gem_name, version
|
274
|
+
# HACK Dependency objects should be immutable
|
227
275
|
dep.prerelease = true if prerelease
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
}
|
276
|
+
|
277
|
+
set = find_gems_with_sources(dep)
|
278
|
+
set.match_platform!
|
232
279
|
end
|
233
280
|
|
234
|
-
if
|
235
|
-
raise Gem::
|
236
|
-
"Could not find a valid gem '#{gem_name}' (#{version}) locally or in a repository",
|
237
|
-
gem_name, version, @errors)
|
281
|
+
if set.empty?
|
282
|
+
raise Gem::SpecificGemNotFoundException.new(gem_name, version, @errors)
|
238
283
|
end
|
239
284
|
|
240
|
-
@
|
285
|
+
@available = set
|
241
286
|
end
|
242
287
|
|
243
288
|
##
|
@@ -258,33 +303,49 @@ class Gem::DependencyInstaller
|
|
258
303
|
if String === dep_or_name then
|
259
304
|
find_spec_by_name_and_version dep_or_name, version, @prerelease
|
260
305
|
else
|
261
|
-
|
262
|
-
|
306
|
+
dep = dep_or_name.dup
|
307
|
+
dep.prerelease = @prerelease
|
308
|
+
@available = find_gems_with_sources(dep).pick_best!
|
263
309
|
end
|
264
310
|
|
265
311
|
@installed_gems = []
|
266
312
|
|
267
313
|
gather_dependencies
|
268
314
|
|
315
|
+
# REFACTOR is the last gem always the one that the user requested?
|
316
|
+
# This code assumes that but is that actually validated by the code?
|
317
|
+
|
269
318
|
last = @gems_to_install.size - 1
|
270
319
|
@gems_to_install.each_with_index do |spec, index|
|
320
|
+
# REFACTOR more current spec set hardcoding, should be abstracted?
|
271
321
|
next if Gem::Specification.include?(spec) and index != last
|
272
322
|
|
273
323
|
# TODO: make this sorta_verbose so other users can benefit from it
|
274
324
|
say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose
|
275
325
|
|
276
|
-
|
326
|
+
source = @available.source_for spec
|
327
|
+
|
277
328
|
begin
|
278
|
-
|
279
|
-
|
329
|
+
# REFACTOR make the fetcher to use configurable
|
330
|
+
local_gem_path = source.download spec, @cache_dir
|
280
331
|
rescue Gem::RemoteFetcher::FetchError
|
332
|
+
# TODO I doubt all fetch errors are recoverable, we should at least
|
333
|
+
# report the errors probably.
|
281
334
|
next if @force
|
282
335
|
raise
|
283
336
|
end
|
284
337
|
|
338
|
+
if @development
|
339
|
+
if @dev_shallow
|
340
|
+
is_dev = @toplevel_specs.include? spec.full_name
|
341
|
+
else
|
342
|
+
is_dev = true
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
285
346
|
inst = Gem::Installer.new local_gem_path,
|
286
347
|
:bin_dir => @bin_dir,
|
287
|
-
:development =>
|
348
|
+
:development => is_dev,
|
288
349
|
:env_shebang => @env_shebang,
|
289
350
|
:force => @force,
|
290
351
|
:format_executable => @format_executable,
|
@@ -299,6 +360,33 @@ class Gem::DependencyInstaller
|
|
299
360
|
@installed_gems << spec
|
300
361
|
end
|
301
362
|
|
363
|
+
# Since this is currently only called for docs, we can be lazy and just say
|
364
|
+
# it's documentation. Ideally the hook adder could decide whether to be in
|
365
|
+
# the background or not, and what to call it.
|
366
|
+
in_background "Installing documentation" do
|
367
|
+
start = Time.now
|
368
|
+
Gem.done_installing_hooks.each do |hook|
|
369
|
+
hook.call self, @installed_gems
|
370
|
+
end
|
371
|
+
finish = Time.now
|
372
|
+
say "Done installing documentation for #{@installed_gems.map(&:name).join(', ')} (#{(finish-start).to_i} sec)."
|
373
|
+
end unless Gem.done_installing_hooks.empty?
|
374
|
+
|
302
375
|
@installed_gems
|
303
376
|
end
|
377
|
+
|
378
|
+
def in_background what
|
379
|
+
fork_happened = false
|
380
|
+
if @build_docs_in_background and Process.respond_to?(:fork)
|
381
|
+
begin
|
382
|
+
Process.fork do
|
383
|
+
yield
|
384
|
+
end
|
385
|
+
fork_happened = true
|
386
|
+
say "#{what} in a background process."
|
387
|
+
rescue NotImplementedError
|
388
|
+
end
|
389
|
+
end
|
390
|
+
yield unless fork_happened
|
391
|
+
end
|
304
392
|
end
|