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
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems/remote_fetcher'
|
2
2
|
|
3
3
|
module Gem::GemcutterUtilities
|
4
|
+
# TODO: move to Gem::Command
|
4
5
|
OptionParser.accept Symbol do |value|
|
5
6
|
value.to_sym
|
6
7
|
end
|
@@ -19,6 +20,8 @@ module Gem::GemcutterUtilities
|
|
19
20
|
def api_key
|
20
21
|
if options[:key] then
|
21
22
|
verify_api_key options[:key]
|
23
|
+
elsif Gem.configuration.api_keys.key?(host)
|
24
|
+
Gem.configuration.api_keys[host]
|
22
25
|
else
|
23
26
|
Gem.configuration.rubygems_api_key
|
24
27
|
end
|
@@ -44,12 +47,24 @@ module Gem::GemcutterUtilities
|
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
|
-
|
50
|
+
attr_writer :host
|
51
|
+
def host
|
52
|
+
configured_host = Gem.host unless
|
53
|
+
Gem.configuration.disable_default_gem_server
|
54
|
+
|
55
|
+
@host ||= ENV['RUBYGEMS_HOST'] || configured_host
|
56
|
+
end
|
57
|
+
|
58
|
+
def rubygems_api_request(method, path, host = nil, &block)
|
48
59
|
require 'net/http'
|
49
|
-
host = ENV['RUBYGEMS_HOST'] if ENV['RUBYGEMS_HOST']
|
50
|
-
uri = URI.parse "#{host}/#{path}"
|
51
60
|
|
52
|
-
|
61
|
+
self.host = host if host
|
62
|
+
unless self.host
|
63
|
+
alert_error "You must specify a gem server"
|
64
|
+
terminate_interaction 1 # TODO: question this
|
65
|
+
end
|
66
|
+
|
67
|
+
uri = URI.parse "#{self.host}/#{path}"
|
53
68
|
|
54
69
|
request_method = Net::HTTP.const_get method.to_s.capitalize
|
55
70
|
|
@@ -66,7 +81,7 @@ module Gem::GemcutterUtilities
|
|
66
81
|
end
|
67
82
|
else
|
68
83
|
say resp.body
|
69
|
-
terminate_interaction 1
|
84
|
+
terminate_interaction 1 # TODO: question this
|
70
85
|
end
|
71
86
|
end
|
72
87
|
|
@@ -74,8 +89,8 @@ module Gem::GemcutterUtilities
|
|
74
89
|
if Gem.configuration.api_keys.key? key then
|
75
90
|
Gem.configuration.api_keys[key]
|
76
91
|
else
|
77
|
-
alert_error "No such API key.
|
78
|
-
terminate_interaction 1
|
92
|
+
alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)."
|
93
|
+
terminate_interaction 1 # TODO: question this
|
79
94
|
end
|
80
95
|
end
|
81
96
|
|
data/lib/rubygems/indexer.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'rubygems/
|
2
|
+
require 'rubygems/package'
|
3
3
|
require 'time'
|
4
4
|
|
5
5
|
begin
|
@@ -15,11 +15,6 @@ class Gem::Indexer
|
|
15
15
|
|
16
16
|
include Gem::UserInteraction
|
17
17
|
|
18
|
-
##
|
19
|
-
# Build indexes for RubyGems older than 1.2.0 when true
|
20
|
-
|
21
|
-
attr_accessor :build_legacy
|
22
|
-
|
23
18
|
##
|
24
19
|
# Build indexes for RubyGems 1.2.0 and newer when true
|
25
20
|
|
@@ -63,15 +58,10 @@ class Gem::Indexer
|
|
63
58
|
"\n\tgem install builder"
|
64
59
|
end
|
65
60
|
|
66
|
-
options = { :
|
61
|
+
options = { :build_modern => true }.merge options
|
67
62
|
|
68
|
-
@build_legacy = options[:build_legacy]
|
69
63
|
@build_modern = options[:build_modern]
|
70
64
|
|
71
|
-
@rss_title = options[:rss_title]
|
72
|
-
@rss_host = options[:rss_host]
|
73
|
-
@rss_gems_host = options[:rss_gems_host]
|
74
|
-
|
75
65
|
@dest_directory = directory
|
76
66
|
@directory = File.join(Dir.tmpdir, "gem_generate_index_#{$$}")
|
77
67
|
|
@@ -99,8 +89,6 @@ class Gem::Indexer
|
|
99
89
|
@dest_prerelease_specs_index =
|
100
90
|
File.join(@dest_directory, "prerelease_specs.#{Gem.marshal_version}")
|
101
91
|
|
102
|
-
@rss_index = File.join @directory, 'index.rss'
|
103
|
-
|
104
92
|
@files = []
|
105
93
|
end
|
106
94
|
|
@@ -109,6 +97,8 @@ class Gem::Indexer
|
|
109
97
|
# searching, downloading and related activities and do not need deployment
|
110
98
|
# specific information (e.g. list of files). So we abbreviate the spec,
|
111
99
|
# making it much smaller for quicker downloads.
|
100
|
+
#--
|
101
|
+
# TODO move to Gem::Specification
|
112
102
|
|
113
103
|
def abbreviate(spec)
|
114
104
|
spec.files = []
|
@@ -123,37 +113,15 @@ class Gem::Indexer
|
|
123
113
|
# Build various indicies
|
124
114
|
|
125
115
|
def build_indicies
|
126
|
-
# Marshal gemspecs are used by both modern and legacy RubyGems
|
127
|
-
|
128
116
|
Gem::Specification.dirs = []
|
129
117
|
Gem::Specification.add_specs(*map_gems_to_specs(gem_file_list))
|
130
118
|
|
131
119
|
build_marshal_gemspecs
|
132
|
-
build_legacy_indicies if @build_legacy
|
133
120
|
build_modern_indicies if @build_modern
|
134
|
-
build_rss
|
135
121
|
|
136
122
|
compress_indicies
|
137
123
|
end
|
138
124
|
|
139
|
-
##
|
140
|
-
# Builds indicies for RubyGems older than 1.2.x
|
141
|
-
|
142
|
-
def build_legacy_indicies
|
143
|
-
index = collect_specs
|
144
|
-
|
145
|
-
say "Generating Marshal master index"
|
146
|
-
|
147
|
-
Gem.time 'Generated Marshal master index' do
|
148
|
-
open @marshal_index, 'wb' do |io|
|
149
|
-
io.write index.dump
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
@files << @marshal_index
|
154
|
-
@files << "#{@marshal_index}.Z"
|
155
|
-
end
|
156
|
-
|
157
125
|
##
|
158
126
|
# Builds Marshal quick index gemspecs.
|
159
127
|
|
@@ -238,104 +206,6 @@ class Gem::Indexer
|
|
238
206
|
"#{@prerelease_specs_index}.gz"]
|
239
207
|
end
|
240
208
|
|
241
|
-
##
|
242
|
-
# Builds an RSS feed for past two days gem releases according to the gem's
|
243
|
-
# date.
|
244
|
-
|
245
|
-
def build_rss
|
246
|
-
if @rss_host.nil? or @rss_gems_host.nil? then
|
247
|
-
if Gem.configuration.really_verbose then
|
248
|
-
alert_warning "no --rss-host or --rss-gems-host, RSS generation disabled"
|
249
|
-
end
|
250
|
-
return
|
251
|
-
end
|
252
|
-
|
253
|
-
require 'cgi'
|
254
|
-
require 'rubygems/text'
|
255
|
-
|
256
|
-
extend Gem::Text
|
257
|
-
|
258
|
-
Gem.time 'Generated rss' do
|
259
|
-
open @rss_index, 'wb' do |io|
|
260
|
-
rss_host = CGI.escapeHTML @rss_host
|
261
|
-
rss_title = CGI.escapeHTML(@rss_title || 'gems')
|
262
|
-
|
263
|
-
io.puts <<-HEADER
|
264
|
-
<?xml version="1.0"?>
|
265
|
-
<rss version="2.0">
|
266
|
-
<channel>
|
267
|
-
<title>#{rss_title}</title>
|
268
|
-
<link>http://#{rss_host}</link>
|
269
|
-
<description>Recently released gems from http://#{rss_host}</description>
|
270
|
-
<generator>RubyGems v#{Gem::VERSION}</generator>
|
271
|
-
<docs>http://cyber.law.harvard.edu/rss/rss.html</docs>
|
272
|
-
HEADER
|
273
|
-
|
274
|
-
today = Gem::Specification::TODAY
|
275
|
-
yesterday = today - 86400
|
276
|
-
|
277
|
-
index = Gem::Specification.select do |spec|
|
278
|
-
spec_date = spec.date
|
279
|
-
# TODO: remove this and make YAML based specs properly normalized
|
280
|
-
spec_date = Time.parse(spec_date.to_s) if Date === spec_date
|
281
|
-
|
282
|
-
spec_date >= yesterday && spec_date <= today
|
283
|
-
end
|
284
|
-
|
285
|
-
index.sort_by { |spec| [-spec.date.to_i, spec] }.each do |spec|
|
286
|
-
file_name = File.basename spec.cache_file
|
287
|
-
gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{file_name}"
|
288
|
-
size = File.stat(spec.loaded_from).size # rescue next
|
289
|
-
|
290
|
-
description = spec.description || spec.summary || ''
|
291
|
-
authors = Array spec.authors
|
292
|
-
emails = Array spec.email
|
293
|
-
authors = emails.zip(authors).map do |email, author|
|
294
|
-
email += " (#{author})" if author and not author.empty?
|
295
|
-
end.join ', '
|
296
|
-
|
297
|
-
description = description.split(/\n\n+/).map do |chunk|
|
298
|
-
format_text chunk, 78
|
299
|
-
end
|
300
|
-
|
301
|
-
description = description.join "\n\n"
|
302
|
-
|
303
|
-
item = ''
|
304
|
-
|
305
|
-
item << <<-ITEM
|
306
|
-
<item>
|
307
|
-
<title>#{CGI.escapeHTML spec.full_name}</title>
|
308
|
-
<description>
|
309
|
-
<pre>#{CGI.escapeHTML description.chomp}</pre>
|
310
|
-
</description>
|
311
|
-
<author>#{CGI.escapeHTML authors}</author>
|
312
|
-
<guid>#{CGI.escapeHTML spec.full_name}</guid>
|
313
|
-
<enclosure url=\"#{gem_path}\"
|
314
|
-
length=\"#{size}\" type=\"application/octet-stream\" />
|
315
|
-
<pubDate>#{spec.date.rfc2822}</pubDate>
|
316
|
-
ITEM
|
317
|
-
|
318
|
-
item << <<-ITEM if spec.homepage
|
319
|
-
<link>#{CGI.escapeHTML spec.homepage}</link>
|
320
|
-
ITEM
|
321
|
-
|
322
|
-
item << <<-ITEM
|
323
|
-
</item>
|
324
|
-
ITEM
|
325
|
-
|
326
|
-
io.puts item
|
327
|
-
end
|
328
|
-
|
329
|
-
io.puts <<-FOOTER
|
330
|
-
</channel>
|
331
|
-
</rss>
|
332
|
-
FOOTER
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
@files << @rss_index
|
337
|
-
end
|
338
|
-
|
339
209
|
def map_gems_to_specs gems
|
340
210
|
gems.map { |gemfile|
|
341
211
|
if File.size(gemfile) == 0 then
|
@@ -344,7 +214,7 @@ class Gem::Indexer
|
|
344
214
|
end
|
345
215
|
|
346
216
|
begin
|
347
|
-
spec = Gem::
|
217
|
+
spec = Gem::Package.new(gemfile).spec
|
348
218
|
spec.loaded_from = gemfile
|
349
219
|
|
350
220
|
# HACK: fuck this shit - borks all tests that use pl1
|
@@ -373,21 +243,6 @@ class Gem::Indexer
|
|
373
243
|
}.compact
|
374
244
|
end
|
375
245
|
|
376
|
-
##
|
377
|
-
# Collect specifications from .gem files from the gem directory.
|
378
|
-
|
379
|
-
def collect_specs(gems = gem_file_list)
|
380
|
-
Gem::Deprecate.skip_during do
|
381
|
-
index = Gem::SourceIndex.new
|
382
|
-
|
383
|
-
map_gems_to_specs(gems).each do |spec|
|
384
|
-
index.add_spec spec, spec.original_name
|
385
|
-
end
|
386
|
-
|
387
|
-
index
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
246
|
##
|
392
247
|
# Compresses indicies on disk
|
393
248
|
#--
|
@@ -397,11 +252,6 @@ class Gem::Indexer
|
|
397
252
|
say "Compressing indicies"
|
398
253
|
|
399
254
|
Gem.time 'Compressed indicies' do
|
400
|
-
if @build_legacy then
|
401
|
-
compress @marshal_index, 'Z'
|
402
|
-
paranoid @marshal_index, 'Z'
|
403
|
-
end
|
404
|
-
|
405
255
|
if @build_modern then
|
406
256
|
gzip @specs_index
|
407
257
|
gzip @latest_specs_index
|
@@ -559,12 +409,9 @@ class Gem::Indexer
|
|
559
409
|
end
|
560
410
|
|
561
411
|
##
|
562
|
-
# Perform an in-place update of the repository from newly added gems.
|
563
|
-
# works for modern indicies, and sets #build_legacy to false when run.
|
412
|
+
# Perform an in-place update of the repository from newly added gems.
|
564
413
|
|
565
414
|
def update_index
|
566
|
-
@build_legacy = false
|
567
|
-
|
568
415
|
make_temp_directories
|
569
416
|
|
570
417
|
specs_mtime = File.stat(@dest_specs_index).mtime
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubygems/user_interaction'
|
3
|
+
|
4
|
+
##
|
5
|
+
# A default post-install hook that displays "Successfully installed
|
6
|
+
# some_gem-1.0"
|
7
|
+
|
8
|
+
Gem.post_install do |installer|
|
9
|
+
ui = Gem::DefaultUserInteraction.ui
|
10
|
+
ui.say "Successfully installed #{installer.spec.full_name}"
|
11
|
+
end
|
12
|
+
|
@@ -22,6 +22,7 @@ module Gem::InstallUpdateOptions
|
|
22
22
|
# Add the install/update options to the option parser.
|
23
23
|
|
24
24
|
def add_install_update_options
|
25
|
+
# TODO: use @parser.accept
|
25
26
|
OptionParser.accept Gem::Security::Policy do |value|
|
26
27
|
require 'rubygems/security'
|
27
28
|
|
@@ -39,21 +40,49 @@ module Gem::InstallUpdateOptions
|
|
39
40
|
end
|
40
41
|
|
41
42
|
add_option(:"Install/Update", '-n', '--bindir DIR',
|
42
|
-
|
43
|
-
|
43
|
+
'Directory where binary files are',
|
44
|
+
'located') do |value, options|
|
44
45
|
options[:bin_dir] = File.expand_path(value)
|
45
46
|
end
|
46
47
|
|
47
|
-
add_option(:"Install/Update",
|
48
|
-
'Generate
|
49
|
-
'
|
50
|
-
|
48
|
+
add_option(:"Install/Update", '--[no-]document [TYPES]', Array,
|
49
|
+
'Generate documentation for installed gems',
|
50
|
+
'List the documentation types you wish to',
|
51
|
+
'generate. For example: rdoc,ri') do |value, options|
|
52
|
+
options[:document] = case value
|
53
|
+
when nil then %w[ri]
|
54
|
+
when false then []
|
55
|
+
else value
|
56
|
+
end
|
51
57
|
end
|
52
58
|
|
53
|
-
add_option(:"Install/Update", '--
|
54
|
-
'
|
55
|
-
|
56
|
-
|
59
|
+
add_option(:"Install/Update", '-N', '--no-document',
|
60
|
+
'Disable documentation generation') do |value, options|
|
61
|
+
options[:document] = []
|
62
|
+
end
|
63
|
+
|
64
|
+
add_option(:Deprecated, '--[no-]rdoc',
|
65
|
+
'Generate RDoc for installed gems',
|
66
|
+
'Use --document instead') do |value, options|
|
67
|
+
if value then
|
68
|
+
options[:document] << 'rdoc'
|
69
|
+
else
|
70
|
+
options[:document].delete 'rdoc'
|
71
|
+
end
|
72
|
+
|
73
|
+
options[:document].uniq!
|
74
|
+
end
|
75
|
+
|
76
|
+
add_option(:Deprecated, '--[no-]ri',
|
77
|
+
'Generate ri data for installed gems.',
|
78
|
+
'Use --document instead') do |value, options|
|
79
|
+
if value then
|
80
|
+
options[:document] << 'ri'
|
81
|
+
else
|
82
|
+
options[:document].delete 'ri'
|
83
|
+
end
|
84
|
+
|
85
|
+
options[:document].uniq!
|
57
86
|
end
|
58
87
|
|
59
88
|
add_option(:"Install/Update", '-E', '--[no-]env-shebang',
|
@@ -85,12 +114,6 @@ module Gem::InstallUpdateOptions
|
|
85
114
|
options[:ignore_dependencies] = value
|
86
115
|
end
|
87
116
|
|
88
|
-
add_option(:"Install/Update", '-y', '--include-dependencies',
|
89
|
-
'Unconditionally install the required',
|
90
|
-
'dependent gems') do |value, options|
|
91
|
-
options[:include_dependencies] = value
|
92
|
-
end
|
93
|
-
|
94
117
|
add_option(:"Install/Update", '--[no-]format-executable',
|
95
118
|
'Make installed executable names match ruby.',
|
96
119
|
'If ruby is ruby18, foo_exec will be',
|
@@ -105,15 +128,30 @@ module Gem::InstallUpdateOptions
|
|
105
128
|
end
|
106
129
|
|
107
130
|
add_option(:"Install/Update", "--development",
|
108
|
-
"Install
|
131
|
+
"Install additional development",
|
109
132
|
"dependencies") do |value, options|
|
110
133
|
options[:development] = true
|
134
|
+
options[:dev_shallow] = true
|
135
|
+
end
|
136
|
+
|
137
|
+
add_option(:"Install/Update", "--development-all",
|
138
|
+
"Install development dependencies for all",
|
139
|
+
"gems (including dev deps themselves)") do |value, options|
|
140
|
+
options[:development] = true
|
141
|
+
options[:dev_shallow] = false
|
111
142
|
end
|
112
143
|
|
113
144
|
add_option(:"Install/Update", "--conservative",
|
114
145
|
"Don't attempt to upgrade gems already",
|
115
146
|
"meeting version requirement") do |value, options|
|
116
147
|
options[:conservative] = true
|
148
|
+
options[:minimal_deps] = true
|
149
|
+
end
|
150
|
+
|
151
|
+
add_option(:"Install/Update", "--minimal-deps",
|
152
|
+
"Don't upgrade any dependencies that already",
|
153
|
+
"meet version requirements") do |value, options|
|
154
|
+
options[:minimal_deps] = true
|
117
155
|
end
|
118
156
|
end
|
119
157
|
|
@@ -121,7 +159,7 @@ module Gem::InstallUpdateOptions
|
|
121
159
|
# Default options for the gem install command.
|
122
160
|
|
123
161
|
def install_update_defaults_str
|
124
|
-
'--rdoc --
|
162
|
+
'--document=rdoc,ri --wrappers'
|
125
163
|
end
|
126
164
|
|
127
165
|
end
|
data/lib/rubygems/installer.rb
CHANGED
@@ -4,15 +4,13 @@
|
|
4
4
|
# See LICENSE.txt for permissions.
|
5
5
|
#++
|
6
6
|
|
7
|
-
require 'rubygems/format'
|
8
7
|
require 'rubygems/exceptions'
|
8
|
+
require 'rubygems/package'
|
9
9
|
require 'rubygems/ext'
|
10
|
-
require 'rubygems/require_paths_builder'
|
11
10
|
require 'rubygems/user_interaction'
|
12
11
|
|
13
12
|
##
|
14
|
-
# The installer
|
15
|
-
# contained in the .gem into the Gem.path.
|
13
|
+
# The installer installs the files contained in the .gem into the Gem.home.
|
16
14
|
#
|
17
15
|
# Gem::Installer does the work of putting files in all the right places on the
|
18
16
|
# filesystem including unpacking the gem into its gem dir, installing the
|
@@ -39,8 +37,7 @@ class Gem::Installer
|
|
39
37
|
|
40
38
|
include Gem::UserInteraction
|
41
39
|
|
42
|
-
|
43
|
-
|
40
|
+
# DOC: Missing docs or :nodoc:.
|
44
41
|
attr_reader :gem
|
45
42
|
|
46
43
|
##
|
@@ -67,6 +64,7 @@ class Gem::Installer
|
|
67
64
|
|
68
65
|
attr_accessor :path_warning
|
69
66
|
|
67
|
+
# DOC: Missing docs or :nodoc:.
|
70
68
|
attr_writer :exec_format
|
71
69
|
|
72
70
|
# Defaults to use Ruby's program prefix and suffix.
|
@@ -80,24 +78,36 @@ class Gem::Installer
|
|
80
78
|
# Constructs an Installer instance that will install the gem located at
|
81
79
|
# +gem+. +options+ is a Hash with the following keys:
|
82
80
|
#
|
81
|
+
# :bin_dir:: Where to put a bin wrapper if needed.
|
82
|
+
# :development:: Whether or not development dependencies should be installed.
|
83
83
|
# :env_shebang:: Use /usr/bin/env in bin wrappers.
|
84
84
|
# :force:: Overrides all version checks and security policy checks, except
|
85
85
|
# for a signed-gems-only policy.
|
86
|
-
# :ignore_dependencies:: Don't raise if a dependency is missing.
|
87
|
-
# :install_dir:: The directory to install the gem into.
|
88
86
|
# :format_executable:: Format the executable the same as the ruby executable.
|
89
87
|
# If your ruby is ruby18, foo_exec will be installed as
|
90
88
|
# foo_exec18.
|
89
|
+
# :ignore_dependencies:: Don't raise if a dependency is missing.
|
90
|
+
# :install_dir:: The directory to install the gem into.
|
91
91
|
# :security_policy:: Use the specified security policy. See Gem::Security
|
92
|
+
# :user_install:: Indicate that the gem should be unpacked into the users
|
93
|
+
# personal gem directory.
|
94
|
+
# :only_install_dir:: Only validate dependencies against what is in the
|
95
|
+
# install_dir
|
92
96
|
# :wrappers:: Install wrappers if true, symlinks if false.
|
97
|
+
# :build_args:: An Array of arguments to pass to the extension builder
|
98
|
+
# process. If not set, then Gem::Command.build_args is used
|
93
99
|
|
94
100
|
def initialize(gem, options={})
|
95
101
|
require 'fileutils'
|
96
102
|
|
97
103
|
@gem = gem
|
98
104
|
@options = options
|
105
|
+
@package = Gem::Package.new @gem
|
106
|
+
|
99
107
|
process_options
|
100
108
|
|
109
|
+
@package.security_policy = @security_policy
|
110
|
+
|
101
111
|
if options[:user_install] and not options[:unpack] then
|
102
112
|
@gem_home = Gem.user_dir
|
103
113
|
check_that_user_bin_dir_is_in_path
|
@@ -105,28 +115,79 @@ class Gem::Installer
|
|
105
115
|
end
|
106
116
|
|
107
117
|
##
|
108
|
-
#
|
118
|
+
# Checks if +filename+ exists in +@bin_dir+.
|
119
|
+
#
|
120
|
+
# If +@force+ is set +filename+ is overwritten.
|
121
|
+
#
|
122
|
+
# If +filename+ exists and is a RubyGems wrapper for different gem the user
|
123
|
+
# is consulted.
|
124
|
+
#
|
125
|
+
# If +filename+ exists and +@bin_dir+ is Gem.default_bindir (/usr/local) the
|
126
|
+
# user is consulted.
|
127
|
+
#
|
128
|
+
# Otherwise +filename+ is overwritten.
|
109
129
|
|
110
|
-
def
|
111
|
-
|
130
|
+
def check_executable_overwrite filename # :nodoc:
|
131
|
+
return if @force
|
132
|
+
|
133
|
+
generated_bin = File.join @bin_dir, filename
|
134
|
+
|
135
|
+
return unless File.exist? generated_bin
|
136
|
+
|
137
|
+
ruby_executable = false
|
138
|
+
existing = nil
|
139
|
+
|
140
|
+
open generated_bin, 'rb' do |io|
|
141
|
+
next unless io.gets =~ /^#!/ # shebang
|
142
|
+
io.gets # blankline
|
143
|
+
|
144
|
+
# TODO detect a specially formatted comment instead of trying
|
145
|
+
# to run a regexp against ruby code.
|
146
|
+
next unless io.gets =~ /This file was generated by RubyGems/
|
147
|
+
|
148
|
+
ruby_executable = true
|
149
|
+
existing = io.read.slice(/^gem (['"])(.*?)(\1),/, 2)
|
150
|
+
end
|
151
|
+
|
152
|
+
return if spec.name == existing
|
153
|
+
|
154
|
+
# somebody has written to RubyGems' directory, overwrite, too bad
|
155
|
+
return if Gem.default_bindir != @bin_dir and not ruby_executable
|
156
|
+
|
157
|
+
question = "#{spec.name}'s executable \"#{filename}\" conflicts with "
|
158
|
+
|
159
|
+
if ruby_executable then
|
160
|
+
question << existing
|
161
|
+
|
162
|
+
return if ask_yes_no "#{question}\nOverwrite the executable?", false
|
163
|
+
|
164
|
+
conflict = "installed executable from #{existing}"
|
165
|
+
else
|
166
|
+
question << generated_bin
|
167
|
+
|
168
|
+
return if ask_yes_no "#{question}\nOverwrite the executable?", false
|
169
|
+
|
170
|
+
conflict = generated_bin
|
171
|
+
end
|
172
|
+
|
173
|
+
raise Gem::InstallError,
|
174
|
+
"\"#{filename}\" from #{spec.name} conflicts with #{conflict}"
|
112
175
|
end
|
113
176
|
|
114
177
|
##
|
115
|
-
# Lazy accessor for the
|
178
|
+
# Lazy accessor for the spec's gem directory.
|
116
179
|
|
117
|
-
def
|
118
|
-
|
119
|
-
@format ||= Gem::Format.from_file_by_path gem, @security_policy
|
120
|
-
rescue Gem::Package::FormatError
|
121
|
-
raise Gem::InstallError, "invalid gem format for #{gem}"
|
122
|
-
end
|
180
|
+
def gem_dir
|
181
|
+
@gem_dir ||= File.join(gem_home, "gems", spec.full_name)
|
123
182
|
end
|
124
183
|
|
125
184
|
##
|
126
185
|
# Lazy accessor for the installer's spec.
|
127
186
|
|
128
187
|
def spec
|
129
|
-
@spec ||=
|
188
|
+
@spec ||= @package.spec
|
189
|
+
rescue Gem::Package::Error => e
|
190
|
+
raise Gem::InstallError, "invalid gem: #{e.message}"
|
130
191
|
end
|
131
192
|
|
132
193
|
##
|
@@ -141,11 +202,7 @@ class Gem::Installer
|
|
141
202
|
# specifications/<gem-version>.gemspec #=> the Gem::Specification
|
142
203
|
|
143
204
|
def install
|
144
|
-
current_home = Gem.dir
|
145
|
-
current_path = Gem.paths.path
|
146
|
-
|
147
205
|
verify_gem_home(options[:unpack])
|
148
|
-
Gem.use_paths gem_home, current_path # HACK: shouldn't need Gem.paths.path
|
149
206
|
|
150
207
|
# If we're forcing the install then disable security unless the security
|
151
208
|
# policy says that we only install signed gems.
|
@@ -158,65 +215,96 @@ class Gem::Installer
|
|
158
215
|
ensure_dependencies_met unless @ignore_dependencies
|
159
216
|
end
|
160
217
|
|
161
|
-
|
162
|
-
result = hook.call self
|
163
|
-
|
164
|
-
if result == false then
|
165
|
-
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
|
166
|
-
|
167
|
-
message = "pre-install hook#{location} failed for #{spec.full_name}"
|
168
|
-
raise Gem::InstallError, message
|
169
|
-
end
|
170
|
-
end
|
218
|
+
run_pre_install_hooks
|
171
219
|
|
172
220
|
Gem.ensure_gem_subdirectories gem_home
|
173
221
|
|
174
222
|
# Completely remove any previous gem files
|
175
|
-
FileUtils.rm_rf(gem_dir)
|
223
|
+
FileUtils.rm_rf(gem_dir)
|
176
224
|
|
177
225
|
FileUtils.mkdir_p gem_dir
|
178
226
|
|
179
227
|
extract_files
|
180
228
|
build_extensions
|
181
229
|
|
182
|
-
|
183
|
-
result = hook.call self
|
184
|
-
|
185
|
-
if result == false then
|
186
|
-
FileUtils.rm_rf gem_dir
|
230
|
+
run_post_build_hooks
|
187
231
|
|
188
|
-
|
232
|
+
generate_bin
|
233
|
+
write_spec
|
189
234
|
|
190
|
-
|
191
|
-
|
235
|
+
unless @build_args.empty?
|
236
|
+
File.open spec.build_info_file, "w" do |f|
|
237
|
+
@build_args.each { |a| f.puts a }
|
192
238
|
end
|
193
239
|
end
|
194
240
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE
|
241
|
+
# TODO should be always cache the file? Other classes have options
|
242
|
+
# to controls if caching is done.
|
243
|
+
cache_file = File.join(gem_home, "cache", "#{spec.full_name}.gem")
|
199
244
|
|
200
|
-
cache_file = spec.cache_file
|
201
245
|
FileUtils.cp gem, cache_file unless File.exist? cache_file
|
202
246
|
|
203
247
|
say spec.post_install_message unless spec.post_install_message.nil?
|
204
248
|
|
205
|
-
spec.loaded_from =
|
249
|
+
spec.loaded_from = spec_file
|
206
250
|
|
207
251
|
Gem::Specification.add_spec spec unless Gem::Specification.include? spec
|
208
252
|
|
253
|
+
run_post_install_hooks
|
254
|
+
|
255
|
+
spec
|
256
|
+
|
257
|
+
# TODO This rescue is in the wrong place. What is raising this exception?
|
258
|
+
# move this rescue to arround the code that actually might raise it.
|
259
|
+
rescue Zlib::GzipFile::Error
|
260
|
+
raise Gem::InstallError, "gzip error installing #{gem}"
|
261
|
+
end
|
262
|
+
|
263
|
+
def run_pre_install_hooks # :nodoc:
|
264
|
+
Gem.pre_install_hooks.each do |hook|
|
265
|
+
if hook.call(self) == false then
|
266
|
+
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
|
267
|
+
|
268
|
+
message = "pre-install hook#{location} failed for #{spec.full_name}"
|
269
|
+
raise Gem::InstallError, message
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def run_post_build_hooks # :nodoc:
|
275
|
+
Gem.post_build_hooks.each do |hook|
|
276
|
+
if hook.call(self) == false then
|
277
|
+
FileUtils.rm_rf gem_dir
|
278
|
+
|
279
|
+
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
|
280
|
+
|
281
|
+
message = "post-build hook#{location} failed for #{spec.full_name}"
|
282
|
+
raise Gem::InstallError, message
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def run_post_install_hooks # :nodoc:
|
209
288
|
Gem.post_install_hooks.each do |hook|
|
210
289
|
hook.call self
|
211
290
|
end
|
291
|
+
end
|
212
292
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
293
|
+
##
|
294
|
+
#
|
295
|
+
# Return an Array of Specifications contained within the gem_home
|
296
|
+
# we'll be installing into.
|
297
|
+
|
298
|
+
def installed_specs
|
299
|
+
@specs ||= begin
|
300
|
+
specs = []
|
301
|
+
|
302
|
+
Dir[File.join(gem_home, "specifications", "*.gemspec")].each do |path|
|
303
|
+
spec = Gem::Specification.load path.untaint
|
304
|
+
specs << spec if spec
|
305
|
+
end
|
306
|
+
|
307
|
+
specs
|
220
308
|
end
|
221
309
|
end
|
222
310
|
|
@@ -235,9 +323,11 @@ class Gem::Installer
|
|
235
323
|
end
|
236
324
|
|
237
325
|
##
|
238
|
-
# True if the gems in the
|
326
|
+
# True if the gems in the system satisfy +dependency+.
|
239
327
|
|
240
328
|
def installation_satisfies_dependency?(dependency)
|
329
|
+
return true if installed_specs.detect { |s| dependency.matches_spec? s }
|
330
|
+
return false if @only_install_dir
|
241
331
|
not dependency.matching_specs.empty?
|
242
332
|
end
|
243
333
|
|
@@ -246,18 +336,23 @@ class Gem::Installer
|
|
246
336
|
|
247
337
|
def unpack(directory)
|
248
338
|
@gem_dir = directory
|
249
|
-
@format = Gem::Format.from_file_by_path gem, @security_policy
|
250
339
|
extract_files
|
251
340
|
end
|
252
341
|
|
342
|
+
##
|
343
|
+
# The location of of the spec file that is installed.
|
344
|
+
#
|
345
|
+
|
346
|
+
def spec_file
|
347
|
+
File.join gem_home, "specifications", "#{spec.full_name}.gemspec"
|
348
|
+
end
|
349
|
+
|
253
350
|
##
|
254
351
|
# Writes the .gemspec specification (in Ruby) to the gem home's
|
255
352
|
# specifications directory.
|
256
353
|
|
257
354
|
def write_spec
|
258
|
-
|
259
|
-
|
260
|
-
File.open(file_name, "w") do |file|
|
355
|
+
File.open(spec_file, "w") do |file|
|
261
356
|
file.puts spec.to_ruby_for_cache
|
262
357
|
end
|
263
358
|
end
|
@@ -277,34 +372,34 @@ class Gem::Installer
|
|
277
372
|
end
|
278
373
|
end
|
279
374
|
|
375
|
+
# DOC: Missing docs or :nodoc:.
|
280
376
|
def generate_bin
|
281
377
|
return if spec.executables.nil? or spec.executables.empty?
|
282
378
|
|
283
|
-
|
284
|
-
|
285
|
-
# (or use) a new bin dir under the gem_home.
|
286
|
-
bindir = @bin_dir || Gem.bindir(gem_home)
|
287
|
-
|
288
|
-
Dir.mkdir bindir unless File.exist? bindir
|
289
|
-
raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
|
379
|
+
Dir.mkdir @bin_dir unless File.exist? @bin_dir
|
380
|
+
raise Gem::FilePermissionError.new(@bin_dir) unless File.writable? @bin_dir
|
290
381
|
|
291
382
|
spec.executables.each do |filename|
|
292
383
|
filename.untaint
|
293
|
-
bin_path = File.
|
384
|
+
bin_path = File.join gem_dir, spec.bindir, filename
|
294
385
|
|
295
|
-
unless File.exist? bin_path
|
296
|
-
|
386
|
+
unless File.exist? bin_path then
|
387
|
+
# TODO change this to a more useful warning
|
388
|
+
warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?"
|
297
389
|
next
|
298
390
|
end
|
299
391
|
|
300
392
|
mode = File.stat(bin_path).mode | 0111
|
301
393
|
FileUtils.chmod mode, bin_path
|
302
394
|
|
395
|
+
check_executable_overwrite filename
|
396
|
+
|
303
397
|
if @wrappers then
|
304
|
-
generate_bin_script filename,
|
398
|
+
generate_bin_script filename, @bin_dir
|
305
399
|
else
|
306
|
-
generate_bin_symlink filename,
|
400
|
+
generate_bin_symlink filename, @bin_dir
|
307
401
|
end
|
402
|
+
|
308
403
|
end
|
309
404
|
end
|
310
405
|
|
@@ -358,10 +453,21 @@ class Gem::Installer
|
|
358
453
|
##
|
359
454
|
# Generates a #! line for +bin_file_name+'s wrapper copying arguments if
|
360
455
|
# necessary.
|
456
|
+
#
|
457
|
+
# If the :custom_shebang config is set, then it is used as a template
|
458
|
+
# for how to create the shebang used for to run a gem's executables.
|
459
|
+
#
|
460
|
+
# The template supports 4 expansions:
|
461
|
+
#
|
462
|
+
# $env the path to the unix env utility
|
463
|
+
# $ruby the path to the currently running ruby interpreter
|
464
|
+
# $exec the path to the gem's executable
|
465
|
+
# $name the name of the gem the executable is for
|
466
|
+
#
|
361
467
|
|
362
468
|
def shebang(bin_file_name)
|
363
469
|
ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
|
364
|
-
path = spec.
|
470
|
+
path = File.join gem_dir, spec.bindir, bin_file_name
|
365
471
|
first_line = File.open(path, "rb") {|file| file.gets}
|
366
472
|
|
367
473
|
if /\A#!/ =~ first_line then
|
@@ -371,7 +477,25 @@ class Gem::Installer
|
|
371
477
|
shebang.strip! # Avoid nasty ^M issues.
|
372
478
|
end
|
373
479
|
|
374
|
-
if
|
480
|
+
if which = Gem.configuration[:custom_shebang]
|
481
|
+
# replace bin_file_name with "ruby" to avoid endless loops
|
482
|
+
which = which.gsub(/ #{bin_file_name}$/," #{Gem::ConfigMap[:ruby_install_name]}")
|
483
|
+
|
484
|
+
which = which.gsub(/\$(\w+)/) do
|
485
|
+
case $1
|
486
|
+
when "env"
|
487
|
+
@env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
|
488
|
+
when "ruby"
|
489
|
+
"#{Gem.ruby}#{opts}"
|
490
|
+
when "exec"
|
491
|
+
bin_file_name
|
492
|
+
when "name"
|
493
|
+
spec.name
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
"#!#{which}"
|
498
|
+
elsif not ruby_name then
|
375
499
|
"#!#{Gem.ruby}#{opts}"
|
376
500
|
elsif opts then
|
377
501
|
"#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
|
@@ -382,6 +506,7 @@ class Gem::Installer
|
|
382
506
|
end
|
383
507
|
end
|
384
508
|
|
509
|
+
# DOC: Missing docs or :nodoc:.
|
385
510
|
def ensure_required_ruby_version_met
|
386
511
|
if rrv = spec.required_ruby_version then
|
387
512
|
unless rrv.satisfied_by? Gem.ruby_version then
|
@@ -390,9 +515,10 @@ class Gem::Installer
|
|
390
515
|
end
|
391
516
|
end
|
392
517
|
|
518
|
+
# DOC: Missing docs or :nodoc:.
|
393
519
|
def ensure_required_rubygems_version_met
|
394
520
|
if rrgv = spec.required_rubygems_version then
|
395
|
-
unless rrgv.satisfied_by? Gem
|
521
|
+
unless rrgv.satisfied_by? Gem.rubygems_version then
|
396
522
|
raise Gem::InstallError,
|
397
523
|
"#{spec.name} requires RubyGems version #{rrgv}. " +
|
398
524
|
"Try 'gem update --system' to update RubyGems itself."
|
@@ -400,6 +526,7 @@ class Gem::Installer
|
|
400
526
|
end
|
401
527
|
end
|
402
528
|
|
529
|
+
# DOC: Missing docs or :nodoc:.
|
403
530
|
def ensure_dependencies_met
|
404
531
|
deps = spec.runtime_dependencies
|
405
532
|
deps |= spec.development_dependencies if @development
|
@@ -409,13 +536,14 @@ class Gem::Installer
|
|
409
536
|
end
|
410
537
|
end
|
411
538
|
|
539
|
+
# DOC: Missing docs or :nodoc:.
|
412
540
|
def process_options
|
413
541
|
@options = {
|
414
542
|
:bin_dir => nil,
|
415
543
|
:env_shebang => false,
|
416
|
-
:exec_format => false,
|
417
544
|
:force => false,
|
418
545
|
:install_dir => Gem.dir,
|
546
|
+
:only_install_dir => false
|
419
547
|
}.merge options
|
420
548
|
|
421
549
|
@env_shebang = options[:env_shebang]
|
@@ -425,13 +553,18 @@ class Gem::Installer
|
|
425
553
|
@format_executable = options[:format_executable]
|
426
554
|
@security_policy = options[:security_policy]
|
427
555
|
@wrappers = options[:wrappers]
|
428
|
-
@
|
556
|
+
@only_install_dir = options[:only_install_dir]
|
557
|
+
|
558
|
+
# If the user has asked for the gem to be installed in a directory that is
|
559
|
+
# the system gem directory, then use the system bin directory, else create
|
560
|
+
# (or use) a new bin dir under the gem_home.
|
561
|
+
@bin_dir = options[:bin_dir] || Gem.bindir(gem_home)
|
429
562
|
@development = options[:development]
|
430
563
|
|
431
|
-
|
432
|
-
options[:source_index]
|
564
|
+
@build_args = options[:build_args] || Gem::Command.build_args
|
433
565
|
end
|
434
566
|
|
567
|
+
# DOC: Missing docs or :nodoc:.
|
435
568
|
def check_that_user_bin_dir_is_in_path
|
436
569
|
user_bin_dir = @bin_dir || Gem.bindir(gem_home)
|
437
570
|
user_bin_dir.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
|
@@ -449,6 +582,7 @@ class Gem::Installer
|
|
449
582
|
end
|
450
583
|
end
|
451
584
|
|
585
|
+
# DOC: Missing docs or :nodoc:.
|
452
586
|
def verify_gem_home(unpack = false)
|
453
587
|
FileUtils.mkdir_p gem_home
|
454
588
|
raise Gem::FilePermissionError, gem_home unless
|
@@ -499,7 +633,6 @@ GOTO :EOF
|
|
499
633
|
:WinNT
|
500
634
|
@"#{ruby}" "%~dpn0" %*
|
501
635
|
TEXT
|
502
|
-
|
503
636
|
end
|
504
637
|
|
505
638
|
##
|
@@ -508,7 +641,14 @@ TEXT
|
|
508
641
|
|
509
642
|
def build_extensions
|
510
643
|
return if spec.extensions.empty?
|
511
|
-
|
644
|
+
|
645
|
+
if @build_args.empty?
|
646
|
+
say "Building native extensions. This could take a while..."
|
647
|
+
else
|
648
|
+
say "Building native extensions with: '#{@build_args.join(' ')}'"
|
649
|
+
say "This could take a while..."
|
650
|
+
end
|
651
|
+
|
512
652
|
dest_path = File.join gem_dir, spec.require_paths.first
|
513
653
|
ran_rake = false # only run rake once
|
514
654
|
|
@@ -516,6 +656,9 @@ TEXT
|
|
516
656
|
break if ran_rake
|
517
657
|
results = []
|
518
658
|
|
659
|
+
extension ||= ""
|
660
|
+
extension_dir = File.join gem_dir, File.dirname(extension)
|
661
|
+
|
519
662
|
builder = case extension
|
520
663
|
when /extconf/ then
|
521
664
|
Gem::Ext::ExtConfBuilder
|
@@ -525,45 +668,41 @@ TEXT
|
|
525
668
|
ran_rake = true
|
526
669
|
Gem::Ext::RakeBuilder
|
527
670
|
else
|
528
|
-
|
529
|
-
|
671
|
+
message = "No builder for extension '#{extension}'"
|
672
|
+
extension_build_error extension_dir, message
|
530
673
|
end
|
531
674
|
|
532
|
-
|
533
|
-
extension_dir = begin
|
534
|
-
File.join gem_dir, File.dirname(extension)
|
535
|
-
rescue TypeError # extension == nil
|
536
|
-
gem_dir
|
537
|
-
end
|
538
|
-
|
539
|
-
|
540
675
|
begin
|
541
|
-
|
542
|
-
|
543
|
-
|
676
|
+
Dir.chdir extension_dir do
|
677
|
+
results = builder.build(extension, gem_dir, dest_path,
|
678
|
+
results, @build_args)
|
544
679
|
|
545
|
-
|
546
|
-
end
|
680
|
+
say results.join("\n") if Gem.configuration.really_verbose
|
547
681
|
end
|
548
682
|
rescue
|
549
|
-
|
683
|
+
extension_build_error(extension_dir, results.join("\n"))
|
684
|
+
end
|
685
|
+
end
|
686
|
+
end
|
550
687
|
|
551
|
-
|
688
|
+
##
|
689
|
+
# Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
|
690
|
+
|
691
|
+
def extension_build_error(build_dir, output)
|
692
|
+
gem_make_out = File.join build_dir, 'gem_make.out'
|
552
693
|
|
553
|
-
|
694
|
+
open gem_make_out, 'wb' do |io| io.puts output end
|
554
695
|
|
555
|
-
|
696
|
+
message = <<-EOF
|
556
697
|
ERROR: Failed to build gem native extension.
|
557
698
|
|
558
|
-
|
699
|
+
#{output}
|
559
700
|
|
560
701
|
Gem files will remain installed in #{gem_dir} for inspection.
|
561
702
|
Results logged to #{gem_make_out}
|
562
703
|
EOF
|
563
704
|
|
564
|
-
|
565
|
-
end
|
566
|
-
end
|
705
|
+
raise ExtensionBuildError, message
|
567
706
|
end
|
568
707
|
|
569
708
|
##
|
@@ -572,36 +711,7 @@ EOF
|
|
572
711
|
# Ensures that files can't be installed outside the gem directory.
|
573
712
|
|
574
713
|
def extract_files
|
575
|
-
|
576
|
-
|
577
|
-
@format.file_entries.each do |entry, file_data|
|
578
|
-
path = entry['path'].untaint
|
579
|
-
|
580
|
-
if path.start_with? "/" then # for extra sanity
|
581
|
-
raise Gem::InstallError, "attempt to install file into #{entry['path']}"
|
582
|
-
end
|
583
|
-
|
584
|
-
path = File.expand_path File.join(gem_dir, path)
|
585
|
-
|
586
|
-
unless path.start_with? gem_dir then
|
587
|
-
msg = "attempt to install file into %p under %s" %
|
588
|
-
[entry['path'], gem_dir]
|
589
|
-
raise Gem::InstallError, msg
|
590
|
-
end
|
591
|
-
|
592
|
-
FileUtils.rm_rf(path) if File.exist? path
|
593
|
-
|
594
|
-
dir = File.dirname path
|
595
|
-
FileUtils.mkdir_p dir unless File.exist? dir
|
596
|
-
|
597
|
-
File.open(path, "wb") do |out|
|
598
|
-
out.write file_data
|
599
|
-
end
|
600
|
-
|
601
|
-
FileUtils.chmod entry['mode'], path
|
602
|
-
|
603
|
-
say path if Gem.configuration.really_verbose
|
604
|
-
end
|
714
|
+
@package.extract_files gem_dir
|
605
715
|
end
|
606
716
|
|
607
717
|
##
|