slimgems 1.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. data/ChangeLog +5811 -0
  2. data/History.txt +887 -0
  3. data/LICENSE.txt +51 -0
  4. data/README.md +87 -0
  5. data/Rakefile +120 -0
  6. data/bin/gem +25 -0
  7. data/bin/update_slimgems +35 -0
  8. data/bootstrap/Rakefile +4 -0
  9. data/hide_lib_for_update/note.txt +5 -0
  10. data/lib/gauntlet_rubygems.rb +50 -0
  11. data/lib/rbconfig/datadir.rb +20 -0
  12. data/lib/rubygems.rb +1220 -0
  13. data/lib/rubygems/builder.rb +102 -0
  14. data/lib/rubygems/command.rb +534 -0
  15. data/lib/rubygems/command_manager.rb +182 -0
  16. data/lib/rubygems/commands/build_command.rb +53 -0
  17. data/lib/rubygems/commands/cert_command.rb +86 -0
  18. data/lib/rubygems/commands/check_command.rb +80 -0
  19. data/lib/rubygems/commands/cleanup_command.rb +106 -0
  20. data/lib/rubygems/commands/contents_command.rb +98 -0
  21. data/lib/rubygems/commands/dependency_command.rb +195 -0
  22. data/lib/rubygems/commands/environment_command.rb +132 -0
  23. data/lib/rubygems/commands/fetch_command.rb +67 -0
  24. data/lib/rubygems/commands/generate_index_command.rb +133 -0
  25. data/lib/rubygems/commands/help_command.rb +172 -0
  26. data/lib/rubygems/commands/install_command.rb +178 -0
  27. data/lib/rubygems/commands/list_command.rb +35 -0
  28. data/lib/rubygems/commands/lock_command.rb +110 -0
  29. data/lib/rubygems/commands/mirror_command.rb +111 -0
  30. data/lib/rubygems/commands/outdated_command.rb +33 -0
  31. data/lib/rubygems/commands/owner_command.rb +75 -0
  32. data/lib/rubygems/commands/pristine_command.rb +93 -0
  33. data/lib/rubygems/commands/push_command.rb +56 -0
  34. data/lib/rubygems/commands/query_command.rb +280 -0
  35. data/lib/rubygems/commands/rdoc_command.rb +91 -0
  36. data/lib/rubygems/commands/search_command.rb +31 -0
  37. data/lib/rubygems/commands/server_command.rb +86 -0
  38. data/lib/rubygems/commands/setup_command.rb +387 -0
  39. data/lib/rubygems/commands/sources_command.rb +157 -0
  40. data/lib/rubygems/commands/specification_command.rb +125 -0
  41. data/lib/rubygems/commands/stale_command.rb +27 -0
  42. data/lib/rubygems/commands/uninstall_command.rb +83 -0
  43. data/lib/rubygems/commands/unpack_command.rb +121 -0
  44. data/lib/rubygems/commands/update_command.rb +212 -0
  45. data/lib/rubygems/commands/which_command.rb +86 -0
  46. data/lib/rubygems/config_file.rb +345 -0
  47. data/lib/rubygems/custom_require.rb +44 -0
  48. data/lib/rubygems/defaults.rb +101 -0
  49. data/lib/rubygems/dependency.rb +227 -0
  50. data/lib/rubygems/dependency_installer.rb +286 -0
  51. data/lib/rubygems/dependency_list.rb +208 -0
  52. data/lib/rubygems/doc_manager.rb +242 -0
  53. data/lib/rubygems/errors.rb +35 -0
  54. data/lib/rubygems/exceptions.rb +91 -0
  55. data/lib/rubygems/ext.rb +18 -0
  56. data/lib/rubygems/ext/builder.rb +56 -0
  57. data/lib/rubygems/ext/configure_builder.rb +25 -0
  58. data/lib/rubygems/ext/ext_conf_builder.rb +24 -0
  59. data/lib/rubygems/ext/rake_builder.rb +39 -0
  60. data/lib/rubygems/format.rb +81 -0
  61. data/lib/rubygems/gem_openssl.rb +92 -0
  62. data/lib/rubygems/gem_path_searcher.rb +100 -0
  63. data/lib/rubygems/gem_runner.rb +79 -0
  64. data/lib/rubygems/gemcutter_utilities.rb +49 -0
  65. data/lib/rubygems/indexer.rb +720 -0
  66. data/lib/rubygems/install_update_options.rb +125 -0
  67. data/lib/rubygems/installer.rb +604 -0
  68. data/lib/rubygems/local_remote_options.rb +135 -0
  69. data/lib/rubygems/old_format.rb +153 -0
  70. data/lib/rubygems/package.rb +97 -0
  71. data/lib/rubygems/package/f_sync_dir.rb +23 -0
  72. data/lib/rubygems/package/tar_header.rb +266 -0
  73. data/lib/rubygems/package/tar_input.rb +222 -0
  74. data/lib/rubygems/package/tar_output.rb +144 -0
  75. data/lib/rubygems/package/tar_reader.rb +106 -0
  76. data/lib/rubygems/package/tar_reader/entry.rb +141 -0
  77. data/lib/rubygems/package/tar_writer.rb +241 -0
  78. data/lib/rubygems/package_task.rb +126 -0
  79. data/lib/rubygems/platform.rb +183 -0
  80. data/lib/rubygems/remote_fetcher.rb +414 -0
  81. data/lib/rubygems/require_paths_builder.rb +18 -0
  82. data/lib/rubygems/requirement.rb +153 -0
  83. data/lib/rubygems/security.rb +814 -0
  84. data/lib/rubygems/server.rb +872 -0
  85. data/lib/rubygems/source_index.rb +597 -0
  86. data/lib/rubygems/source_info_cache.rb +395 -0
  87. data/lib/rubygems/source_info_cache_entry.rb +56 -0
  88. data/lib/rubygems/spec_fetcher.rb +337 -0
  89. data/lib/rubygems/specification.rb +1486 -0
  90. data/lib/rubygems/test_utilities.rb +147 -0
  91. data/lib/rubygems/text.rb +65 -0
  92. data/lib/rubygems/uninstaller.rb +278 -0
  93. data/lib/rubygems/user_interaction.rb +527 -0
  94. data/lib/rubygems/validator.rb +240 -0
  95. data/lib/rubygems/version.rb +316 -0
  96. data/lib/rubygems/version_option.rb +65 -0
  97. data/lib/ubygems.rb +10 -0
  98. data/setup.rb +42 -0
  99. data/test/bogussources.rb +8 -0
  100. data/test/data/gem-private_key.pem +27 -0
  101. data/test/data/gem-public_cert.pem +20 -0
  102. data/test/fake_certlib/openssl.rb +7 -0
  103. data/test/foo/discover.rb +0 -0
  104. data/test/functional.rb +92 -0
  105. data/test/gem_installer_test_case.rb +97 -0
  106. data/test/gem_package_tar_test_case.rb +132 -0
  107. data/test/gemutilities.rb +605 -0
  108. data/test/insure_session.rb +43 -0
  109. data/test/mockgemui.rb +56 -0
  110. data/test/plugin/exception/rubygems_plugin.rb +2 -0
  111. data/test/plugin/load/rubygems_plugin.rb +1 -0
  112. data/test/plugin/standarderror/rubygems_plugin.rb +2 -0
  113. data/test/private_key.pem +27 -0
  114. data/test/public_cert.pem +20 -0
  115. data/test/rubygems_plugin.rb +21 -0
  116. data/test/simple_gem.rb +66 -0
  117. data/test/test_config.rb +12 -0
  118. data/test/test_gem.rb +766 -0
  119. data/test/test_gem_builder.rb +27 -0
  120. data/test/test_gem_command.rb +178 -0
  121. data/test/test_gem_command_manager.rb +207 -0
  122. data/test/test_gem_commands_build_command.rb +74 -0
  123. data/test/test_gem_commands_cert_command.rb +124 -0
  124. data/test/test_gem_commands_check_command.rb +18 -0
  125. data/test/test_gem_commands_contents_command.rb +156 -0
  126. data/test/test_gem_commands_dependency_command.rb +216 -0
  127. data/test/test_gem_commands_environment_command.rb +144 -0
  128. data/test/test_gem_commands_fetch_command.rb +76 -0
  129. data/test/test_gem_commands_generate_index_command.rb +135 -0
  130. data/test/test_gem_commands_install_command.rb +315 -0
  131. data/test/test_gem_commands_list_command.rb +36 -0
  132. data/test/test_gem_commands_lock_command.rb +68 -0
  133. data/test/test_gem_commands_mirror_command.rb +60 -0
  134. data/test/test_gem_commands_outdated_command.rb +40 -0
  135. data/test/test_gem_commands_owner_command.rb +105 -0
  136. data/test/test_gem_commands_pristine_command.rb +108 -0
  137. data/test/test_gem_commands_push_command.rb +81 -0
  138. data/test/test_gem_commands_query_command.rb +426 -0
  139. data/test/test_gem_commands_server_command.rb +59 -0
  140. data/test/test_gem_commands_sources_command.rb +209 -0
  141. data/test/test_gem_commands_specification_command.rb +139 -0
  142. data/test/test_gem_commands_stale_command.rb +38 -0
  143. data/test/test_gem_commands_uninstall_command.rb +83 -0
  144. data/test/test_gem_commands_unpack_command.rb +199 -0
  145. data/test/test_gem_commands_update_command.rb +353 -0
  146. data/test/test_gem_commands_which_command.rb +66 -0
  147. data/test/test_gem_config_file.rb +287 -0
  148. data/test/test_gem_dependency.rb +149 -0
  149. data/test/test_gem_dependency_installer.rb +661 -0
  150. data/test/test_gem_dependency_list.rb +230 -0
  151. data/test/test_gem_doc_manager.rb +31 -0
  152. data/test/test_gem_ext_configure_builder.rb +84 -0
  153. data/test/test_gem_ext_ext_conf_builder.rb +173 -0
  154. data/test/test_gem_ext_rake_builder.rb +81 -0
  155. data/test/test_gem_format.rb +70 -0
  156. data/test/test_gem_gem_path_searcher.rb +78 -0
  157. data/test/test_gem_gem_runner.rb +45 -0
  158. data/test/test_gem_gemcutter_utilities.rb +103 -0
  159. data/test/test_gem_indexer.rb +673 -0
  160. data/test/test_gem_install_update_options.rb +68 -0
  161. data/test/test_gem_installer.rb +857 -0
  162. data/test/test_gem_local_remote_options.rb +97 -0
  163. data/test/test_gem_package_tar_header.rb +130 -0
  164. data/test/test_gem_package_tar_input.rb +112 -0
  165. data/test/test_gem_package_tar_output.rb +97 -0
  166. data/test/test_gem_package_tar_reader.rb +46 -0
  167. data/test/test_gem_package_tar_reader_entry.rb +109 -0
  168. data/test/test_gem_package_tar_writer.rb +144 -0
  169. data/test/test_gem_package_task.rb +59 -0
  170. data/test/test_gem_platform.rb +264 -0
  171. data/test/test_gem_remote_fetcher.rb +740 -0
  172. data/test/test_gem_requirement.rb +292 -0
  173. data/test/test_gem_server.rb +356 -0
  174. data/test/test_gem_silent_ui.rb +113 -0
  175. data/test/test_gem_source_index.rb +461 -0
  176. data/test/test_gem_spec_fetcher.rb +410 -0
  177. data/test/test_gem_specification.rb +1291 -0
  178. data/test/test_gem_stream_ui.rb +218 -0
  179. data/test/test_gem_text.rb +43 -0
  180. data/test/test_gem_uninstaller.rb +146 -0
  181. data/test/test_gem_validator.rb +63 -0
  182. data/test/test_gem_version.rb +181 -0
  183. data/test/test_gem_version_option.rb +89 -0
  184. data/test/test_kernel.rb +59 -0
  185. metadata +413 -0
@@ -0,0 +1,125 @@
1
+ #--
2
+ # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+ require 'rubygems'
8
+ require 'rubygems/security'
9
+
10
+ ##
11
+ # Mixin methods for install and update options for Gem::Commands
12
+
13
+ module Gem::InstallUpdateOptions
14
+
15
+ ##
16
+ # Add the install/update options to the option parser.
17
+
18
+ def add_install_update_options
19
+ OptionParser.accept Gem::Security::Policy do |value|
20
+ value = Gem::Security::Policies[value]
21
+ valid = Gem::Security::Policies.keys.sort
22
+ message = "#{value} (#{valid.join ', '} are valid)"
23
+ raise OptionParser::InvalidArgument, message if value.nil?
24
+ value
25
+ end
26
+
27
+ add_option(:"Install/Update", '-i', '--install-dir DIR',
28
+ 'Gem repository directory to get installed',
29
+ 'gems') do |value, options|
30
+ options[:install_dir] = File.expand_path(value)
31
+ end
32
+
33
+ add_option(:"Install/Update", '-n', '--bindir DIR',
34
+ 'Directory where binary files are',
35
+ 'located') do |value, options|
36
+ options[:bin_dir] = File.expand_path(value)
37
+ end
38
+
39
+ add_option(:"Install/Update", '-d', '--[no-]rdoc',
40
+ 'Generate RDoc documentation for the gem on',
41
+ 'install') do |value, options|
42
+ options[:generate_rdoc] = value
43
+ end
44
+
45
+ add_option(:"Install/Update", '--[no-]ri',
46
+ 'Generate RI documentation for the gem on',
47
+ 'install') do |value, options|
48
+ options[:generate_ri] = value
49
+ end
50
+
51
+ add_option(:"Install/Update", '-E', '--[no-]env-shebang',
52
+ "Rewrite the shebang line on installed",
53
+ "scripts to use /usr/bin/env") do |value, options|
54
+ options[:env_shebang] = value
55
+ end
56
+
57
+ add_option(:"Install/Update", '-f', '--[no-]force',
58
+ 'Force gem to install, bypassing dependency',
59
+ 'checks') do |value, options|
60
+ options[:force] = value
61
+ end
62
+
63
+ add_option(:"Install/Update", '-t', '--[no-]test',
64
+ 'Run unit tests prior to installation') do |value, options|
65
+ options[:test] = value
66
+ end
67
+
68
+ add_option(:"Install/Update", '-w', '--[no-]wrappers',
69
+ 'Use bin wrappers for executables',
70
+ 'Not available on dosish platforms') do |value, options|
71
+ options[:wrappers] = value
72
+ end
73
+
74
+ add_option(:"Install/Update", '-P', '--trust-policy POLICY',
75
+ Gem::Security::Policy,
76
+ 'Specify gem trust policy') do |value, options|
77
+ options[:security_policy] = value
78
+ end
79
+
80
+ add_option(:"Install/Update", '--ignore-dependencies',
81
+ 'Do not install any required dependent gems') do |value, options|
82
+ options[:ignore_dependencies] = value
83
+ end
84
+
85
+ add_option(:"Install/Update", '-y', '--include-dependencies',
86
+ 'Unconditionally install the required',
87
+ 'dependent gems') do |value, options|
88
+ options[:include_dependencies] = value
89
+ end
90
+
91
+ add_option(:"Install/Update", '--[no-]format-executable',
92
+ 'Make installed executable names match ruby.',
93
+ 'If ruby is ruby18, foo_exec will be',
94
+ 'foo_exec18') do |value, options|
95
+ options[:format_executable] = value
96
+ end
97
+
98
+ add_option(:"Install/Update", '--[no-]user-install',
99
+ 'Install in user\'s home directory instead',
100
+ 'of GEM_HOME.') do |value, options|
101
+ options[:user_install] = value
102
+ end
103
+
104
+ add_option(:"Install/Update", "--development",
105
+ "Install any additional development",
106
+ "dependencies") do |value, options|
107
+ options[:development] = true
108
+ end
109
+
110
+ add_option(:"Install/Update", "--conservative",
111
+ "Don't attempt to upgrade gems already",
112
+ "meeting version requirement") do |value, options|
113
+ options[:conservative] = true
114
+ end
115
+ end
116
+
117
+ ##
118
+ # Default options for the gem install command.
119
+
120
+ def install_update_defaults_str
121
+ '--rdoc --no-force --no-test --wrappers'
122
+ end
123
+
124
+ end
125
+
@@ -0,0 +1,604 @@
1
+ #--
2
+ # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+ require 'fileutils'
8
+ require 'rbconfig'
9
+
10
+ require 'rubygems/format'
11
+ require 'rubygems/ext'
12
+ require 'rubygems/require_paths_builder'
13
+
14
+ ##
15
+ # The installer class processes RubyGem .gem files and installs the files
16
+ # contained in the .gem into the Gem.path.
17
+ #
18
+ # Gem::Installer does the work of putting files in all the right places on the
19
+ # filesystem including unpacking the gem into its gem dir, installing the
20
+ # gemspec in the specifications dir, storing the cached gem in the cache dir,
21
+ # and installing either wrappers or symlinks for executables.
22
+ #
23
+ # The installer fires pre and post install hooks. Hooks can be added either
24
+ # through a rubygems_plugin.rb file in an installed gem or via a
25
+ # rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb
26
+ # file. See Gem.pre_install and Gem.post_install for details.
27
+
28
+ class Gem::Installer
29
+
30
+ ##
31
+ # Paths where env(1) might live. Some systems are broken and have it in
32
+ # /bin
33
+
34
+ ENV_PATHS = %w[/usr/bin/env /bin/env]
35
+
36
+ ##
37
+ # Raised when there is an error while building extensions.
38
+ #
39
+ class ExtensionBuildError < Gem::InstallError; end
40
+
41
+ include Gem::UserInteraction
42
+
43
+ include Gem::RequirePathsBuilder
44
+
45
+ ##
46
+ # The directory a gem's executables will be installed into
47
+
48
+ attr_reader :bin_dir
49
+
50
+ ##
51
+ # The gem repository the gem will be installed into
52
+
53
+ attr_reader :gem_home
54
+
55
+ ##
56
+ # The Gem::Specification for the gem being installed
57
+
58
+ attr_reader :spec
59
+
60
+ ##
61
+ # The options passed when the Gem::Installer was instantiated.
62
+
63
+ attr_accessor :options
64
+
65
+ @path_warning = false
66
+
67
+ class << self
68
+
69
+ ##
70
+ # True if we've warned about PATH not including Gem.bindir
71
+
72
+ attr_accessor :path_warning
73
+
74
+ attr_writer :exec_format
75
+
76
+ # Defaults to use Ruby's program prefix and suffix.
77
+ def exec_format
78
+ @exec_format ||= Gem.default_exec_format
79
+ end
80
+
81
+ end
82
+
83
+ ##
84
+ # Constructs an Installer instance that will install the gem located at
85
+ # +gem+. +options+ is a Hash with the following keys:
86
+ #
87
+ # :env_shebang:: Use /usr/bin/env in bin wrappers.
88
+ # :force:: Overrides all version checks and security policy checks, except
89
+ # for a signed-gems-only policy.
90
+ # :ignore_dependencies:: Don't raise if a dependency is missing.
91
+ # :install_dir:: The directory to install the gem into.
92
+ # :format_executable:: Format the executable the same as the ruby executable.
93
+ # If your ruby is ruby18, foo_exec will be installed as
94
+ # foo_exec18.
95
+ # :security_policy:: Use the specified security policy. See Gem::Security
96
+ # :wrappers:: Install wrappers if true, symlinks if false.
97
+
98
+ def initialize(gem, options={})
99
+ @gem = gem
100
+ @options = options
101
+ process_options
102
+ load_gem_file
103
+
104
+ if options[:user_install] and not options[:unpack] then
105
+ @gem_home = Gem.user_dir
106
+ check_that_user_bin_dir_is_in_path
107
+ end
108
+
109
+ verify_gem_home(options[:unpack])
110
+
111
+ @spec = @format.spec
112
+
113
+ @gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
114
+ end
115
+
116
+ ##
117
+ # Installs the gem and returns a loaded Gem::Specification for the installed
118
+ # gem.
119
+ #
120
+ # The gem will be installed with the following structure:
121
+ #
122
+ # @gem_home/
123
+ # cache/<gem-version>.gem #=> a cached copy of the installed gem
124
+ # gems/<gem-version>/... #=> extracted files
125
+ # specifications/<gem-version>.gemspec #=> the Gem::Specification
126
+
127
+ def install
128
+ # If we're forcing the install then disable security unless the security
129
+ # policy says that we only install singed gems.
130
+ @security_policy = nil if @force and @security_policy and
131
+ not @security_policy.only_signed
132
+
133
+ unless @force
134
+ ensure_required_ruby_version_met
135
+ ensure_required_rubygems_version_met
136
+ ensure_dependencies_met unless @ignore_dependencies
137
+ end
138
+
139
+ Gem.pre_install_hooks.each do |hook|
140
+ result = hook.call self
141
+
142
+ if result == false then
143
+ location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
144
+
145
+ message = "pre-install hook#{location} failed for #{spec.full_name}"
146
+ raise Gem::InstallError, message
147
+ end
148
+ end
149
+
150
+ Gem.ensure_gem_subdirectories @gem_home
151
+
152
+ FileUtils.mkdir_p @gem_dir
153
+
154
+ extract_files
155
+ build_extensions
156
+
157
+ Gem.post_build_hooks.each do |hook|
158
+ result = hook.call self
159
+
160
+ if result == false then
161
+ FileUtils.rm_rf @gem_dir
162
+
163
+ location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
164
+
165
+ message = "post-build hook#{location} failed for #{spec.full_name}"
166
+ raise Gem::InstallError, message
167
+ end
168
+ end
169
+
170
+ generate_bin
171
+ write_spec
172
+
173
+ write_require_paths_file_if_needed
174
+
175
+ # HACK remove? Isn't this done in multiple places?
176
+ cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop
177
+ unless File.exist? cached_gem then
178
+ FileUtils.cp @gem, File.join(@gem_home, "cache")
179
+ end
180
+
181
+ unless @spec.post_install_message.nil?
182
+ # Only for SlimGems
183
+ if @spec.name == Gem::GEM_NAME
184
+ lines = @spec.post_install_message.split("\n")
185
+ lines.shift if lines.first.include?("Upgraded from #{Gem::NAME}")
186
+ say lines.join("\n")
187
+ else
188
+ say @spec.post_install_message
189
+ end
190
+ end
191
+
192
+ @spec.loaded_from = File.join(@gem_home, 'specifications', @spec.spec_name)
193
+
194
+ @source_index.add_spec @spec
195
+
196
+ Gem.post_install_hooks.each do |hook|
197
+ hook.call self
198
+ end
199
+
200
+ return @spec
201
+ rescue Zlib::GzipFile::Error
202
+ raise Gem::InstallError, "gzip error installing #{@gem}"
203
+ end
204
+
205
+ ##
206
+ # Ensure that the dependency is satisfied by the current installation of
207
+ # gem. If it is not an exception is raised.
208
+ #
209
+ # spec :: Gem::Specification
210
+ # dependency :: Gem::Dependency
211
+
212
+ def ensure_dependency(spec, dependency)
213
+ unless installation_satisfies_dependency? dependency then
214
+ raise Gem::InstallError, "#{spec.name} requires #{dependency}"
215
+ end
216
+ true
217
+ end
218
+
219
+ ##
220
+ # True if the gems in the source_index satisfy +dependency+.
221
+
222
+ def installation_satisfies_dependency?(dependency)
223
+ @source_index.find_name(dependency.name, dependency.requirement).size > 0
224
+ end
225
+
226
+ ##
227
+ # Unpacks the gem into the given directory.
228
+
229
+ def unpack(directory)
230
+ @gem_dir = directory
231
+ @format = Gem::Format.from_file_by_path @gem, @security_policy
232
+ extract_files
233
+ end
234
+
235
+ ##
236
+ # Writes the .gemspec specification (in Ruby) to the gem home's
237
+ # specifications directory.
238
+
239
+ def write_spec
240
+ rubycode = @spec.to_ruby
241
+
242
+ file_name = File.join @gem_home, 'specifications', @spec.spec_name
243
+
244
+ file_name.untaint
245
+
246
+ File.open(file_name, "w") do |file|
247
+ file.puts rubycode
248
+ end
249
+ end
250
+
251
+ ##
252
+ # Creates windows .bat files for easy running of commands
253
+
254
+ def generate_windows_script(filename, bindir)
255
+ if Gem.win_platform? then
256
+ script_name = filename + ".bat"
257
+ script_path = File.join bindir, File.basename(script_name)
258
+ File.open script_path, 'w' do |file|
259
+ file.puts windows_stub_script(bindir, filename)
260
+ end
261
+
262
+ say script_path if Gem.configuration.really_verbose
263
+ end
264
+ end
265
+
266
+ def generate_bin
267
+ return if @spec.executables.nil? or @spec.executables.empty?
268
+
269
+ # If the user has asked for the gem to be installed in a directory that is
270
+ # the system gem directory, then use the system bin directory, else create
271
+ # (or use) a new bin dir under the gem_home.
272
+ bindir = @bin_dir ? @bin_dir : Gem.bindir(@gem_home)
273
+
274
+ Dir.mkdir bindir unless File.exist? bindir
275
+ raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
276
+
277
+ @spec.executables.each do |filename|
278
+ filename.untaint
279
+ bin_path = File.expand_path "#{@spec.bindir}/#{filename}", @gem_dir
280
+ mode = File.stat(bin_path).mode | 0111
281
+ File.chmod mode, bin_path
282
+
283
+ if @wrappers then
284
+ generate_bin_script filename, bindir
285
+ else
286
+ generate_bin_symlink filename, bindir
287
+ end
288
+ end
289
+ end
290
+
291
+ ##
292
+ # Creates the scripts to run the applications in the gem.
293
+ #--
294
+ # The Windows script is generated in addition to the regular one due to a
295
+ # bug or misfeature in the Windows shell's pipe. See
296
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/193379
297
+
298
+ def generate_bin_script(filename, bindir)
299
+ bin_script_path = File.join bindir, formatted_program_filename(filename)
300
+
301
+ File.join @gem_dir, @spec.bindir, filename
302
+
303
+ # HACK some gems don't have #! in their executables, restore 2008/06
304
+ #if File.read(exec_path, 2) == '#!' then
305
+ FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
306
+
307
+ File.open bin_script_path, 'w', 0755 do |file|
308
+ file.print app_script_text(filename)
309
+ end
310
+
311
+ say bin_script_path if Gem.configuration.really_verbose
312
+
313
+ generate_windows_script filename, bindir
314
+ #else
315
+ # FileUtils.rm_f bin_script_path
316
+ # FileUtils.cp exec_path, bin_script_path,
317
+ # :verbose => Gem.configuration.really_verbose
318
+ #end
319
+ end
320
+
321
+ ##
322
+ # Creates the symlinks to run the applications in the gem. Moves
323
+ # the symlink if the gem being installed has a newer version.
324
+
325
+ def generate_bin_symlink(filename, bindir)
326
+ if Gem.win_platform? then
327
+ alert_warning "Unable to use symlinks on Windows, installing wrapper"
328
+ generate_bin_script filename, bindir
329
+ return
330
+ end
331
+
332
+ src = File.join @gem_dir, 'bin', filename
333
+ dst = File.join bindir, formatted_program_filename(filename)
334
+
335
+ if File.exist? dst then
336
+ if File.symlink? dst then
337
+ link = File.readlink(dst).split File::SEPARATOR
338
+ cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
339
+ return if @spec.version < cur_version
340
+ end
341
+ File.unlink dst
342
+ end
343
+
344
+ FileUtils.symlink src, dst, :verbose => Gem.configuration.really_verbose
345
+ end
346
+
347
+ ##
348
+ # Generates a #! line for +bin_file_name+'s wrapper copying arguments if
349
+ # necessary.
350
+
351
+ def shebang(bin_file_name)
352
+ ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
353
+ path = File.join @gem_dir, @spec.bindir, bin_file_name
354
+ first_line = File.open(path, "rb") {|file| file.gets}
355
+
356
+ if /\A#!/ =~ first_line then
357
+ # Preserve extra words on shebang line, like "-w". Thanks RPA.
358
+ shebang = first_line.sub(/\A\#!.*?ruby\S*(?=(\s+\S+))/, "#!#{Gem.ruby}")
359
+ opts = $1
360
+ shebang.strip! # Avoid nasty ^M issues.
361
+ end
362
+
363
+ if not ruby_name then
364
+ "#!#{Gem.ruby}#{opts}"
365
+ elsif opts then
366
+ "#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
367
+ else
368
+ # Create a plain shebang line.
369
+ @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
370
+ "#!#{@env_path} #{ruby_name}"
371
+ end
372
+ end
373
+
374
+ def ensure_required_ruby_version_met
375
+ if rrv = @spec.required_ruby_version then
376
+ unless rrv.satisfied_by? Gem.ruby_version then
377
+ raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}."
378
+ end
379
+ end
380
+ end
381
+
382
+ def ensure_required_rubygems_version_met
383
+ if rrgv = @spec.required_rubygems_version then
384
+ unless rrgv.satisfied_by? Gem::Version.new(Gem::VERSION) then
385
+ raise Gem::InstallError,
386
+ "#{@spec.name} requires #{Gem::NAME} version #{rrgv}. " +
387
+ "Try 'gem update --system' to update #{Gem::NAME} itself."
388
+ end
389
+ end
390
+ end
391
+
392
+ def ensure_dependencies_met
393
+ deps = @spec.runtime_dependencies
394
+ deps |= @spec.development_dependencies if @development
395
+
396
+ deps.each do |dep_gem|
397
+ ensure_dependency @spec, dep_gem
398
+ end
399
+ end
400
+
401
+ def process_options
402
+ self.options = {
403
+ :bin_dir => nil,
404
+ :env_shebang => false,
405
+ :exec_format => false,
406
+ :force => false,
407
+ :install_dir => Gem.dir,
408
+ :source_index => Gem.source_index,
409
+ }.merge options
410
+
411
+ @env_shebang = options[:env_shebang]
412
+ @force = options[:force]
413
+ gem_home = options[:install_dir]
414
+ @gem_home = File.expand_path(gem_home)
415
+ @ignore_dependencies = options[:ignore_dependencies]
416
+ @format_executable = options[:format_executable]
417
+ @security_policy = options[:security_policy]
418
+ @wrappers = options[:wrappers]
419
+ @bin_dir = options[:bin_dir]
420
+ @development = options[:development]
421
+ @source_index = options[:source_index]
422
+ end
423
+
424
+ def load_gem_file
425
+ begin
426
+ @format = Gem::Format.from_file_by_path @gem, @security_policy
427
+ rescue Gem::Package::FormatError
428
+ raise Gem::InstallError, "invalid gem format for #{@gem}"
429
+ end
430
+ end
431
+
432
+ def check_that_user_bin_dir_is_in_path
433
+ user_bin_dir = File.join(@gem_home, 'bin')
434
+ unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
435
+ unless self.class.path_warning then
436
+ alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
437
+ self.class.path_warning = true
438
+ end
439
+ end
440
+ end
441
+
442
+ def verify_gem_home(unpack = false)
443
+ FileUtils.mkdir_p @gem_home
444
+ raise Gem::FilePermissionError, @gem_home unless
445
+ unpack or File.writable? @gem_home
446
+ end
447
+
448
+ ##
449
+ # Return the text for an application file.
450
+
451
+ def app_script_text(bin_file_name)
452
+ <<-TEXT
453
+ #{shebang bin_file_name}
454
+ #
455
+ # This file was generated by SlimGems.
456
+ #
457
+ # The application '#{@spec.name}' is installed as part of a gem, and
458
+ # this file is here to facilitate running it.
459
+ #
460
+
461
+ require 'rubygems'
462
+
463
+ version = "#{Gem::Requirement.default}"
464
+
465
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
466
+ version = $1
467
+ ARGV.shift
468
+ end
469
+
470
+ gem '#{@spec.name}', version
471
+ load Gem.bin_path('#{@spec.name}', '#{bin_file_name}', version)
472
+ TEXT
473
+ end
474
+
475
+ ##
476
+ # return the stub script text used to launch the true ruby script
477
+
478
+ def windows_stub_script(bindir, bin_file_name)
479
+ <<-TEXT
480
+ @ECHO OFF
481
+ IF NOT "%~f0" == "~f0" GOTO :WinNT
482
+ @"#{File.basename(Gem.ruby).chomp('"')}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
483
+ GOTO :EOF
484
+ :WinNT
485
+ @"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
486
+ TEXT
487
+ end
488
+
489
+ ##
490
+ # Builds extensions. Valid types of extensions are extconf.rb files,
491
+ # configure scripts and rakefiles or mkrf_conf files.
492
+
493
+ def build_extensions
494
+ return if @spec.extensions.empty?
495
+ unless @spec.name == Gem::GEM_NAME
496
+ say "Building native extensions. This could take a while..."
497
+ end
498
+ start_dir = Dir.pwd
499
+ dest_path = File.join @gem_dir, @spec.require_paths.first
500
+ ran_rake = false # only run rake once
501
+
502
+ @spec.extensions.each do |extension|
503
+ break if ran_rake
504
+ results = []
505
+
506
+ builder = case extension
507
+ when /extconf/ then
508
+ Gem::Ext::ExtConfBuilder
509
+ when /configure/ then
510
+ Gem::Ext::ConfigureBuilder
511
+ when /rakefile/i, /mkrf_conf/i then
512
+ ran_rake = true
513
+ Gem::Ext::RakeBuilder
514
+ else
515
+ results = ["No builder for extension '#{extension}'"]
516
+ nil
517
+ end
518
+
519
+ begin
520
+ Dir.chdir File.join(@gem_dir, File.dirname(extension))
521
+ results = builder.build(extension, @gem_dir, dest_path, results)
522
+
523
+ say results.join("\n") if Gem.configuration.really_verbose
524
+
525
+ rescue
526
+ results = results.join "\n"
527
+
528
+ File.open('gem_make.out', 'wb') { |f| f.puts results }
529
+
530
+ message = <<-EOF
531
+ ERROR: Failed to build gem native extension.
532
+
533
+ #{results}
534
+
535
+ Gem files will remain installed in #{@gem_dir} for inspection.
536
+ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
537
+ EOF
538
+
539
+ raise ExtensionBuildError, message
540
+ ensure
541
+ Dir.chdir start_dir
542
+ end
543
+ end
544
+ end
545
+
546
+ ##
547
+ # Reads the file index and extracts each file into the gem directory.
548
+ #
549
+ # Ensures that files can't be installed outside the gem directory.
550
+
551
+ def extract_files
552
+ @gem_dir = File.expand_path @gem_dir
553
+
554
+ raise ArgumentError, "format required to extract from" if @format.nil?
555
+
556
+ dirs = []
557
+
558
+ @format.file_entries.each do |entry, file_data|
559
+ path = entry['path'].untaint
560
+
561
+ if path =~ /\A\// then # for extra sanity
562
+ raise Gem::InstallError,
563
+ "attempt to install file into #{entry['path'].inspect}"
564
+ end
565
+
566
+ path = File.expand_path File.join(@gem_dir, path)
567
+
568
+ if path !~ /\A#{Regexp.escape @gem_dir}/ then
569
+ msg = "attempt to install file into %p under %p" %
570
+ [entry['path'], @gem_dir]
571
+ raise Gem::InstallError, msg
572
+ end
573
+
574
+ FileUtils.rm_rf(path) if File.exists?(path)
575
+
576
+ dir = File.dirname(path)
577
+ if !dirs.include?(dir)
578
+ dirs << dir
579
+ FileUtils.mkdir_p dir
580
+ end
581
+
582
+ File.open(path, "wb") do |out|
583
+ out.write file_data
584
+ end
585
+
586
+ FileUtils.chmod entry['mode'], path
587
+
588
+ say path if Gem.configuration.really_verbose
589
+ end
590
+ end
591
+
592
+ ##
593
+ # Prefix and suffix the program filename the same as ruby.
594
+
595
+ def formatted_program_filename(filename)
596
+ if @format_executable then
597
+ self.class.exec_format % File.basename(filename)
598
+ else
599
+ filename
600
+ end
601
+ end
602
+
603
+ end
604
+