rubygems-update 1.8.30 → 2.0.0.preview2
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.
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
|
##
|