rubygems-update 1.5.3 → 1.6.0

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.

Files changed (79) hide show
  1. data.tar.gz.sig +2 -1
  2. data/History.txt +60 -9
  3. data/Manifest.txt +1 -1
  4. data/Rakefile +0 -2
  5. data/lib/rubygems.rb +142 -65
  6. data/lib/rubygems/commands/owner_command.rb +3 -2
  7. data/lib/rubygems/commands/pristine_command.rb +5 -3
  8. data/lib/rubygems/commands/push_command.rb +8 -4
  9. data/lib/rubygems/commands/setup_command.rb +1 -2
  10. data/lib/rubygems/commands/uninstall_command.rb +5 -0
  11. data/lib/rubygems/commands/unpack_command.rb +10 -16
  12. data/lib/rubygems/config_file.rb +12 -5
  13. data/lib/rubygems/custom_require.rb +27 -7
  14. data/lib/rubygems/dependency.rb +33 -8
  15. data/lib/rubygems/dependency_installer.rb +21 -6
  16. data/lib/rubygems/dependency_list.rb +35 -3
  17. data/lib/rubygems/doc_manager.rb +6 -4
  18. data/lib/rubygems/gem_path_searcher.rb +45 -1
  19. data/lib/rubygems/gemcutter_utilities.rb +33 -0
  20. data/lib/rubygems/indexer.rb +1 -0
  21. data/lib/rubygems/installer.rb +11 -7
  22. data/lib/rubygems/installer_test_case.rb +23 -15
  23. data/lib/rubygems/mock_gem_ui.rb +1 -1
  24. data/lib/rubygems/remote_fetcher.rb +29 -10
  25. data/lib/rubygems/requirement.rb +1 -1
  26. data/lib/rubygems/security.rb +1 -0
  27. data/lib/rubygems/source_index.rb +3 -2
  28. data/lib/rubygems/spec_fetcher.rb +3 -1
  29. data/lib/rubygems/specification.rb +54 -12
  30. data/lib/rubygems/test_case.rb +99 -28
  31. data/lib/rubygems/test_utilities.rb +11 -1
  32. data/lib/rubygems/uninstaller.rb +22 -11
  33. data/lib/rubygems/user_interaction.rb +50 -29
  34. data/lib/rubygems/validator.rb +1 -1
  35. data/test/rubygems/fix_openssl_warnings.rb +12 -0
  36. data/test/rubygems/plugin/load/rubygems_plugin.rb +3 -1
  37. data/test/rubygems/test_gem.rb +384 -38
  38. data/test/rubygems/test_gem_builder.rb +1 -1
  39. data/test/rubygems/test_gem_command_manager.rb +2 -2
  40. data/test/rubygems/test_gem_commands_build_command.rb +1 -1
  41. data/test/rubygems/test_gem_commands_cert_command.rb +2 -1
  42. data/test/rubygems/test_gem_commands_dependency_command.rb +6 -5
  43. data/test/rubygems/test_gem_commands_fetch_command.rb +4 -4
  44. data/test/rubygems/test_gem_commands_install_command.rb +21 -18
  45. data/test/rubygems/test_gem_commands_lock_command.rb +1 -1
  46. data/test/rubygems/test_gem_commands_outdated_command.rb +2 -5
  47. data/test/rubygems/test_gem_commands_owner_command.rb +42 -0
  48. data/test/rubygems/test_gem_commands_pristine_command.rb +28 -8
  49. data/test/rubygems/test_gem_commands_push_command.rb +31 -5
  50. data/test/rubygems/test_gem_commands_specification_command.rb +8 -8
  51. data/test/rubygems/test_gem_commands_stale_command.rb +4 -2
  52. data/test/rubygems/test_gem_commands_uninstall_command.rb +23 -4
  53. data/test/rubygems/test_gem_commands_unpack_command.rb +10 -8
  54. data/test/rubygems/test_gem_commands_update_command.rb +16 -13
  55. data/test/rubygems/test_gem_commands_which_command.rb +1 -1
  56. data/test/rubygems/test_gem_config_file.rb +14 -0
  57. data/test/rubygems/test_gem_dependency.rb +39 -0
  58. data/test/rubygems/test_gem_dependency_installer.rb +213 -92
  59. data/test/rubygems/test_gem_dependency_list.rb +37 -17
  60. data/test/rubygems/test_gem_doc_manager.rb +5 -4
  61. data/test/rubygems/test_gem_format.rb +2 -2
  62. data/test/rubygems/test_gem_gemcutter_utilities.rb +48 -0
  63. data/test/rubygems/test_gem_indexer.rb +11 -10
  64. data/test/rubygems/test_gem_install_update_options.rb +0 -2
  65. data/test/rubygems/test_gem_installer.rb +151 -78
  66. data/test/rubygems/test_gem_package_tar_output.rb +3 -0
  67. data/test/rubygems/test_gem_remote_fetcher.rb +23 -14
  68. data/test/rubygems/test_gem_requirement.rb +4 -0
  69. data/test/rubygems/test_gem_security.rb +1 -0
  70. data/test/rubygems/test_gem_source_index.rb +17 -16
  71. data/test/rubygems/test_gem_spec_fetcher.rb +6 -1
  72. data/test/rubygems/test_gem_specification.rb +81 -31
  73. data/test/rubygems/test_gem_stream_ui.rb +11 -1
  74. data/test/rubygems/test_gem_uninstaller.rb +70 -10
  75. data/test/rubygems/test_gem_validator.rb +1 -1
  76. data/test/rubygems/test_kernel.rb +1 -1
  77. metadata +7 -7
  78. metadata.gz.sig +0 -0
  79. data/ChangeLog +0 -5811
@@ -17,6 +17,7 @@ class Gem::Commands::OwnerCommand < Gem::Command
17
17
  def initialize
18
18
  super 'owner', description
19
19
  add_proxy_option
20
+ add_key_option
20
21
  defaults.merge! :add => [], :remove => []
21
22
 
22
23
  add_option '-a', '--add EMAIL', 'Add an owner' do |value, options|
@@ -39,7 +40,7 @@ class Gem::Commands::OwnerCommand < Gem::Command
39
40
 
40
41
  def show_owners name
41
42
  response = rubygems_api_request :get, "api/v1/gems/#{name}/owners.yaml" do |request|
42
- request.add_field "Authorization", Gem.configuration.rubygems_api_key
43
+ request.add_field "Authorization", api_key
43
44
  end
44
45
 
45
46
  with_response response do |resp|
@@ -64,7 +65,7 @@ class Gem::Commands::OwnerCommand < Gem::Command
64
65
  owners.each do |owner|
65
66
  response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
66
67
  request.set_form_data 'email' => owner
67
- request.add_field "Authorization", Gem.configuration.rubygems_api_key
68
+ request.add_field "Authorization", api_key
68
69
  end
69
70
 
70
71
  with_response response
@@ -73,11 +73,13 @@ revert the gem.
73
73
  say "Restoring gem(s) to pristine condition..."
74
74
 
75
75
  specs.each do |spec|
76
- gem = Dir[File.join(Gem.dir, 'cache', spec.file_name)].first
76
+ gem = spec.cache_gem
77
77
 
78
78
  if gem.nil? then
79
- alert_error "Cached gem for #{spec.full_name} not found, use `gem install` to restore"
80
- next
79
+ say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
80
+ dep = Gem::Dependency.new spec.name, spec.version
81
+ Gem::RemoteFetcher.fetcher.download_to_cache dep
82
+ gem = spec.cache_gem
81
83
  end
82
84
 
83
85
  # TODO use installer options
@@ -21,7 +21,8 @@ class Gem::Commands::PushCommand < Gem::Command
21
21
  def initialize
22
22
  super 'push', description
23
23
  add_proxy_option
24
-
24
+ add_key_option
25
+
25
26
  add_option(
26
27
  '--host HOST',
27
28
  'Push to another gemcutter-compatible host'
@@ -36,17 +37,20 @@ class Gem::Commands::PushCommand < Gem::Command
36
37
  end
37
38
 
38
39
  def send_gem name
39
- say "Pushing gem to #{options[:host] || Gem.host}..."
40
-
41
40
  args = [:post, "api/v1/gems"]
42
41
 
43
42
  args << options[:host] if options[:host]
44
43
 
44
+ if Gem.latest_rubygems_version < Gem::Version.new(Gem::VERSION) then
45
+ alert_error "Using beta/unreleased version of rubygems. Not pushing."
46
+ terminate_interaction 1
47
+ end
48
+
45
49
  response = rubygems_api_request(*args) do |request|
46
50
  request.body = Gem.read_binary name
47
51
  request.add_field "Content-Length", request.body.size
48
52
  request.add_field "Content-Type", "application/octet-stream"
49
- request.add_field "Authorization", Gem.configuration.rubygems_api_key
53
+ request.add_field "Authorization", api_key
50
54
  end
51
55
 
52
56
  with_response response
@@ -329,8 +329,7 @@ abort "#{deprecation_message}"
329
329
 
330
330
  require 'rdoc/rdoc'
331
331
 
332
- args << '--quiet'
333
- args << '--main' << 'README.rdoc'
332
+ args << '--main' << 'README.rdoc' << '--quiet'
334
333
  args << '.'
335
334
  args << 'README.rdoc' << 'UPGRADING.rdoc'
336
335
  args << 'LICENSE.txt' << 'GPL.txt' << 'History.txt'
@@ -49,6 +49,11 @@ class Gem::Commands::UninstallCommand < Gem::Command
49
49
  options[:user_install] = value
50
50
  end
51
51
 
52
+ add_option('--[no-]format-executable',
53
+ 'Assume executable names match Ruby\'s prefix and suffix.') do |value, options|
54
+ options[:format_executable] = value
55
+ end
56
+
52
57
  add_version_option
53
58
  add_platform_option
54
59
  end
@@ -1,6 +1,7 @@
1
1
  require 'rubygems/command'
2
2
  require 'rubygems/installer'
3
3
  require 'rubygems/version_option'
4
+ require 'rubygems/remote_fetcher'
4
5
 
5
6
  class Gem::Commands::UnpackCommand < Gem::Command
6
7
 
@@ -33,16 +34,6 @@ class Gem::Commands::UnpackCommand < Gem::Command
33
34
  "#{program_name} GEMNAME"
34
35
  end
35
36
 
36
- def download dependency
37
- found = Gem::SpecFetcher.fetcher.fetch dependency
38
-
39
- return if found.empty?
40
-
41
- spec, source_uri = found.first
42
-
43
- Gem::RemoteFetcher.fetcher.download spec, source_uri
44
- end
45
-
46
37
  #--
47
38
  # TODO: allow, e.g., 'gem unpack rake-0.3.1'. Find a general solution for
48
39
  # this, so that it works for uninstall as well. (And check other commands
@@ -73,8 +64,9 @@ class Gem::Commands::UnpackCommand < Gem::Command
73
64
  # TODO: see comments in get_path() about general service.
74
65
 
75
66
  def find_in_cache(filename)
76
- Gem.path.each do |gem_dir|
77
- this_path = File.join gem_dir, 'cache', filename
67
+
68
+ Gem.path.each do |path|
69
+ this_path = Gem.cache_gem(filename, path)
78
70
  return this_path if File.exist? this_path
79
71
  end
80
72
 
@@ -105,15 +97,17 @@ class Gem::Commands::UnpackCommand < Gem::Command
105
97
 
106
98
  selected = specs.sort_by { |s| s.version }.last
107
99
 
108
- return download(dependency) if selected.nil?
100
+ return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
101
+ selected
109
102
 
110
103
  return unless dependency.name =~ /^#{selected.name}$/i
111
104
 
112
105
  # We expect to find (basename).gem in the 'cache' directory. Furthermore,
113
106
  # the name match must be exact (ignoring case).
114
-
115
- path = find_in_cache(selected.file_name)
116
- return download(dependency) unless path
107
+
108
+ path = find_in_cache selected.file_name
109
+
110
+ return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path
117
111
 
118
112
  path
119
113
  end
@@ -123,6 +123,11 @@ class Gem::ConfigFile
123
123
 
124
124
  attr_reader :rubygems_api_key
125
125
 
126
+ ##
127
+ # Hash of RubyGems.org and alternate API keys
128
+
129
+ attr_reader :api_keys
130
+
126
131
  ##
127
132
  # Create the config file object. +args+ is the list of arguments
128
133
  # from the command line.
@@ -186,7 +191,7 @@ class Gem::ConfigFile
186
191
  @update_sources = @hash[:update_sources] if @hash.key? :update_sources
187
192
  @verbose = @hash[:verbose] if @hash.key? :verbose
188
193
 
189
- load_rubygems_api_key
194
+ load_api_keys
190
195
 
191
196
  Gem.sources = @hash[:sources] if @hash.key? :sources
192
197
  handle_arguments arg_list
@@ -199,10 +204,12 @@ class Gem::ConfigFile
199
204
  File.join(Gem.user_home, '.gem', 'credentials')
200
205
  end
201
206
 
202
- def load_rubygems_api_key
203
- api_key_hash = File.exists?(credentials_path) ? load_file(credentials_path) : @hash
204
-
205
- @rubygems_api_key = api_key_hash[:rubygems_api_key] if api_key_hash.key? :rubygems_api_key
207
+ def load_api_keys
208
+ @api_keys = File.exists?(credentials_path) ? load_file(credentials_path) : @hash
209
+ if @api_keys.key? :rubygems_api_key then
210
+ @rubygems_api_key = @api_keys[:rubygems_api_key]
211
+ @api_keys[:rubygems] = @api_keys.delete :rubygems_api_key unless @api_keys.key? :rubygems
212
+ end
206
213
  end
207
214
 
208
215
  def rubygems_api_key=(api_key)
@@ -6,10 +6,16 @@
6
6
 
7
7
  module Kernel
8
8
 
9
- ##
10
- # The Kernel#require from before RubyGems was loaded.
11
-
12
- alias gem_original_require require
9
+ if defined?(gem_original_require) then
10
+ # Ruby ships with a custom_require, override its require
11
+ remove_method :require
12
+ else
13
+ ##
14
+ # The Kernel#require from before RubyGems was loaded.
15
+
16
+ alias gem_original_require require
17
+ private :gem_original_require
18
+ end
13
19
 
14
20
  ##
15
21
  # When RubyGems is required, Kernel#require is replaced with our own which
@@ -25,8 +31,23 @@ module Kernel
25
31
  # The normal <tt>require</tt> functionality of returning false if
26
32
  # that file has already been loaded is preserved.
27
33
 
28
- def require(path) # :doc:
29
- gem_original_require path
34
+ def require path
35
+ if Gem.unresolved_deps.empty? or Gem.loaded_path? path then
36
+ gem_original_require path
37
+ else
38
+ specs = Gem.searcher.find_in_unresolved path
39
+ unless specs.empty? then
40
+ specs = [specs.last]
41
+ else
42
+ specs = Gem.searcher.find_in_unresolved_tree path
43
+ end
44
+
45
+ specs.each do |spec|
46
+ Gem.activate spec.name, spec.version # FIX: this is dumb
47
+ end
48
+
49
+ return gem_original_require path
50
+ end
30
51
  rescue LoadError => load_error
31
52
  if load_error.message.end_with?(path) and Gem.try_activate(path) then
32
53
  return gem_original_require(path)
@@ -36,7 +57,6 @@ module Kernel
36
57
  end
37
58
 
38
59
  private :require
39
- private :gem_original_require
40
60
 
41
61
  end
42
62
 
@@ -26,11 +26,6 @@ class Gem::Dependency
26
26
 
27
27
  attr_writer :prerelease
28
28
 
29
- ##
30
- # Dependency type.
31
-
32
- attr_reader :type
33
-
34
29
  ##
35
30
  # Constructs a dependency with +name+ and +requirements+. The last
36
31
  # argument can optionally be the dependency type, which defaults to
@@ -66,7 +61,7 @@ class Gem::Dependency
66
61
 
67
62
  def inspect # :nodoc:
68
63
  "<%s type=%p name=%p requirements=%p>" %
69
- [self.class, @type, @name, requirement.to_s]
64
+ [self.class, self.type, self.name, requirement.to_s]
70
65
  end
71
66
 
72
67
  ##
@@ -126,7 +121,18 @@ class Gem::Dependency
126
121
  end
127
122
 
128
123
  def to_s # :nodoc:
129
- "#{name} (#{requirement}, #{type})"
124
+ if type != :runtime then
125
+ "#{name} (#{requirement}, #{type})"
126
+ else
127
+ "#{name} (#{requirement})"
128
+ end
129
+ end
130
+
131
+ ##
132
+ # Dependency type.
133
+
134
+ def type
135
+ @type ||= :runtime
130
136
  end
131
137
 
132
138
  def == other # :nodoc:
@@ -140,7 +146,7 @@ class Gem::Dependency
140
146
  # Dependencies are ordered by name.
141
147
 
142
148
  def <=> other
143
- @name <=> other.name
149
+ self.name <=> other.name
144
150
  end
145
151
 
146
152
  ##
@@ -181,5 +187,24 @@ class Gem::Dependency
181
187
  requirement.satisfied_by?(spec.version)
182
188
  end
183
189
 
190
+ ##
191
+ # Merges the requirements of +other+ into this dependency
192
+
193
+ def merge other
194
+ unless name == other.name then
195
+ raise ArgumentError,
196
+ "#{self} and #{other} have different names"
197
+ end
198
+
199
+ default = Gem::Requirement.default
200
+ self_req = self.requirement
201
+ other_req = other.requirement
202
+
203
+ return self.class.new name, self_req if other_req == default
204
+ return self.class.new name, other_req if self_req == default
205
+
206
+ self.class.new name, self_req.as_list.concat(other_req.as_list)
207
+ end
208
+
184
209
  end
185
210
 
@@ -68,7 +68,7 @@ class Gem::DependencyInstaller
68
68
  @installed_gems = []
69
69
 
70
70
  @install_dir = options[:install_dir] || Gem.dir
71
- @cache_dir = options[:cache_dir] || @install_dir
71
+ @cache_dir = options[:cache_dir] || Gem.cache_dir(@install_dir)
72
72
 
73
73
  # Set with any errors that SpecFetcher finds while search through
74
74
  # gemspecs for a dep
@@ -130,17 +130,33 @@ class Gem::DependencyInstaller
130
130
  def gather_dependencies
131
131
  specs = @specs_and_sources.map { |spec,_| spec }
132
132
 
133
+ # these gems were listed by the user, always install them
134
+ keep_names = specs.map { |spec| spec.full_name }
135
+
133
136
  dependency_list = Gem::DependencyList.new @development
134
137
  dependency_list.add(*specs)
135
138
  to_do = specs.dup
136
139
 
137
140
  add_found_dependencies to_do, dependency_list unless @ignore_dependencies
138
141
 
142
+ dependency_list.specs.reject! { |spec|
143
+ ! keep_names.include? spec.full_name and
144
+ @source_index.any? { |n,_| n == spec.full_name }
145
+ }
146
+
147
+ unless dependency_list.ok? or @ignore_dependencies or @force then
148
+ reason = dependency_list.why_not_ok?.map { |k,v|
149
+ "#{k} requires #{v.join(", ")}"
150
+ }.join("; ")
151
+ raise Gem::DependencyError, "Unable to resolve dependencies: #{reason}"
152
+ end
153
+
139
154
  @gems_to_install = dependency_list.dependency_order.reverse
140
155
  end
141
156
 
142
157
  def add_found_dependencies to_do, dependency_list
143
158
  seen = {}
159
+ dependencies = Hash.new { |h, name| h[name] = Gem::Dependency.new name }
144
160
 
145
161
  until to_do.empty? do
146
162
  spec = to_do.shift
@@ -151,10 +167,10 @@ class Gem::DependencyInstaller
151
167
  deps |= spec.development_dependencies if @development
152
168
 
153
169
  deps.each do |dep|
170
+ dependencies[dep.name] = dependencies[dep.name].merge dep
171
+
154
172
  results = find_gems_with_sources(dep).reverse
155
173
 
156
- # FIX: throw in everything that satisfies, and let
157
- # FIX: dependencylist reduce to the chosen few
158
174
  results.reject! do |dep_spec,|
159
175
  to_do.push dep_spec
160
176
 
@@ -166,14 +182,14 @@ class Gem::DependencyInstaller
166
182
  end
167
183
 
168
184
  results.each do |dep_spec, source_uri|
169
- next if seen[dep_spec.name]
170
185
  @specs_and_sources << [dep_spec, source_uri]
171
186
 
172
- # FIX: this is the bug
173
187
  dependency_list.add dep_spec
174
188
  end
175
189
  end
176
190
  end
191
+
192
+ dependency_list.remove_specs_unsatisfied_by dependencies
177
193
  end
178
194
 
179
195
  ##
@@ -253,7 +269,6 @@ class Gem::DependencyInstaller
253
269
 
254
270
  @gems_to_install.each do |spec|
255
271
  last = spec == @gems_to_install.last
256
- # HACK is this test for full_name acceptable?
257
272
  next if @source_index.any? { |n,_| n == spec.full_name } and not last
258
273
 
259
274
  # TODO: make this sorta_verbose so other users can benefit from it
@@ -11,6 +11,7 @@ require 'tsort'
11
11
  # correct order to avoid conflicts.
12
12
 
13
13
  class Gem::DependencyList
14
+ attr_reader :specs
14
15
 
15
16
  include Enumerable
16
17
  include TSort
@@ -50,6 +51,10 @@ class Gem::DependencyList
50
51
  @specs.push(*gemspecs)
51
52
  end
52
53
 
54
+ def clear
55
+ @specs.clear
56
+ end
57
+
53
58
  ##
54
59
  # Return a list of the gem specifications in the dependency list, sorted in
55
60
  # order so that no gemspec in the list depends on a gemspec earlier in the
@@ -104,11 +109,26 @@ class Gem::DependencyList
104
109
  # Are all the dependencies in the list satisfied?
105
110
 
106
111
  def ok?
107
- @specs.all? do |spec|
108
- spec.runtime_dependencies.all? do |dep|
109
- @specs.find { |s| s.satisfies_requirement? dep }
112
+ why_not_ok?(:quick).empty?
113
+ end
114
+
115
+ def why_not_ok? quick = false
116
+ unsatisfied = Hash.new { |h,k| h[k] = [] }
117
+ source_index = Gem.source_index
118
+ @specs.each do |spec|
119
+ spec.runtime_dependencies.each do |dep|
120
+ inst = source_index.any? { |_, installed_spec|
121
+ dep.name == installed_spec.name and
122
+ dep.requirement.satisfied_by? installed_spec.version
123
+ }
124
+
125
+ unless inst or @specs.find { |s| s.satisfies_requirement? dep } then
126
+ unsatisfied[spec.name] << dep
127
+ return unsatisfied if quick
128
+ end
110
129
  end
111
130
  end
131
+ unsatisfied
112
132
  end
113
133
 
114
134
  ##
@@ -140,6 +160,18 @@ class Gem::DependencyList
140
160
  }
141
161
  end
142
162
 
163
+ ##
164
+ # Remove everything in the DependencyList that matches but doesn't
165
+ # satisfy items in +dependencies+ (a hash of gem names to arrays of
166
+ # dependencies).
167
+
168
+ def remove_specs_unsatisfied_by dependencies
169
+ specs.reject! { |spec|
170
+ dep = dependencies[spec.name]
171
+ dep and not dep.requirement.satisfied_by? spec.version
172
+ }
173
+ end
174
+
143
175
  ##
144
176
  # Removes the gemspec matching +full_name+ from the dependency list
145
177