rubygems-update 2.4.1 → 2.4.2

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.

Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.txt +38 -0
  5. data/README.rdoc +1 -1
  6. data/Rakefile +3 -3
  7. data/lib/rubygems.rb +1 -1
  8. data/lib/rubygems/command_manager.rb +1 -1
  9. data/lib/rubygems/commands/owner_command.rb +3 -1
  10. data/lib/rubygems/commands/update_command.rb +6 -5
  11. data/lib/rubygems/config_file.rb +1 -1
  12. data/lib/rubygems/dependency.rb +4 -2
  13. data/lib/rubygems/dependency_installer.rb +2 -0
  14. data/lib/rubygems/exceptions.rb +2 -2
  15. data/lib/rubygems/installer.rb +13 -4
  16. data/lib/rubygems/local_remote_options.rb +1 -1
  17. data/lib/rubygems/package/tar_reader/entry.rb +2 -0
  18. data/lib/rubygems/rdoc.rb +0 -1
  19. data/lib/rubygems/request/connection_pools.rb +5 -3
  20. data/lib/rubygems/request_set.rb +57 -1
  21. data/lib/rubygems/request_set/gem_dependency_api.rb +58 -10
  22. data/lib/rubygems/request_set/lockfile.rb +13 -5
  23. data/lib/rubygems/resolver.rb +2 -1
  24. data/lib/rubygems/resolver/composed_set.rb +12 -0
  25. data/lib/rubygems/resolver/conflict.rb +2 -2
  26. data/lib/rubygems/resolver/dependency_request.rb +2 -2
  27. data/lib/rubygems/resolver/index_set.rb +1 -1
  28. data/lib/rubygems/resolver/installer_set.rb +6 -0
  29. data/lib/rubygems/resolver/lock_specification.rb +4 -0
  30. data/lib/rubygems/resolver/set.rb +8 -2
  31. data/lib/rubygems/resolver/vendor_set.rb +2 -0
  32. data/lib/rubygems/source.rb +2 -0
  33. data/lib/rubygems/source/git.rb +10 -2
  34. data/lib/rubygems/specification.rb +9 -3
  35. data/lib/rubygems/stub_specification.rb +5 -0
  36. data/lib/rubygems/test_case.rb +1 -1
  37. data/lib/rubygems/test_utilities.rb +2 -0
  38. data/lib/rubygems/user_interaction.rb +10 -0
  39. data/lib/rubygems/util.rb +14 -1
  40. data/test/rubygems/test_gem_commands_setup_command.rb +6 -8
  41. data/test/rubygems/test_gem_commands_uninstall_command.rb +1 -1
  42. data/test/rubygems/test_gem_commands_update_command.rb +28 -0
  43. data/test/rubygems/test_gem_dependency.rb +27 -0
  44. data/test/rubygems/test_gem_dependency_installer.rb +21 -0
  45. data/test/rubygems/test_gem_ext_builder.rb +1 -1
  46. data/test/rubygems/test_gem_impossible_dependencies_error.rb +6 -6
  47. data/test/rubygems/test_gem_installer.rb +27 -3
  48. data/test/rubygems/test_gem_remote_fetcher.rb +4 -0
  49. data/test/rubygems/test_gem_request_connection_pools.rb +37 -0
  50. data/test/rubygems/test_gem_request_set.rb +20 -1
  51. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +95 -9
  52. data/test/rubygems/test_gem_request_set_lockfile.rb +54 -0
  53. data/test/rubygems/test_gem_resolver_composed_set.rb +13 -0
  54. data/test/rubygems/test_gem_resolver_conflict.rb +2 -2
  55. data/test/rubygems/test_gem_resolver_dependency_request.rb +9 -0
  56. data/test/rubygems/test_gem_resolver_installer_set.rb +12 -0
  57. data/test/rubygems/test_gem_resolver_lock_specification.rb +11 -0
  58. data/test/rubygems/test_gem_resolver_vendor_set.rb +3 -1
  59. data/test/rubygems/test_gem_silent_ui.rb +5 -0
  60. data/test/rubygems/test_gem_source.rb +13 -0
  61. data/test/rubygems/test_gem_source_git.rb +15 -0
  62. data/test/rubygems/test_gem_specification.rb +46 -10
  63. data/test/rubygems/test_gem_stub_specification.rb +10 -0
  64. metadata +3 -3
  65. metadata.gz.sig +0 -0
@@ -168,8 +168,12 @@ class Gem::RequestSet::Lockfile
168
168
  dest = File.expand_path(dest)
169
169
  base = File.expand_path(base)
170
170
 
171
- if dest.index(base) == 0
172
- return dest[base.size+1..-1]
171
+ if dest.index(base) == 0 then
172
+ offset = dest[base.size+1..-1]
173
+
174
+ return '.' unless offset
175
+
176
+ offset
173
177
  else
174
178
  dest
175
179
  end
@@ -387,6 +391,8 @@ class Gem::RequestSet::Lockfile
387
391
  skip :newline
388
392
 
389
393
  set = Gem::Resolver::GitSet.new
394
+ set.root_dir = @set.install_dir
395
+
390
396
  last_spec = nil
391
397
 
392
398
  while not @tokens.empty? and :text == peek.first do
@@ -448,7 +454,7 @@ class Gem::RequestSet::Lockfile
448
454
  else
449
455
  dependency = parse_dependency name, data
450
456
 
451
- last_spec.spec.dependencies << dependency
457
+ last_spec.dependencies << dependency
452
458
  end
453
459
 
454
460
  get :r_paren
@@ -477,7 +483,7 @@ class Gem::RequestSet::Lockfile
477
483
  # the first token of the requirements and returns a Gem::Dependency object.
478
484
 
479
485
  def parse_dependency name, op # :nodoc:
480
- return Gem::Dependency.new name unless peek[0] == :text
486
+ return Gem::Dependency.new name, op unless peek[0] == :text
481
487
 
482
488
  _, version, = get :text
483
489
 
@@ -620,8 +626,10 @@ class Gem::RequestSet::Lockfile
620
626
  # Writes the lock file alongside the gem dependencies file
621
627
 
622
628
  def write
629
+ content = to_s
630
+
623
631
  open "#{@gem_deps_file}.lock", 'w' do |io|
624
- io.write to_s
632
+ io.write content
625
633
  end
626
634
  end
627
635
 
@@ -210,8 +210,9 @@ class Gem::Resolver
210
210
 
211
211
  if (skip_dep_gems = skip_gems[dependency.name]) && !skip_dep_gems.empty?
212
212
  matching = all.select do |api_spec|
213
- skip_dep_gems.any?{|s| api_spec.version == s.version}
213
+ skip_dep_gems.any? { |s| api_spec.version == s.version }
214
214
  end
215
+
215
216
  all = matching unless matching.empty?
216
217
  end
217
218
 
@@ -21,6 +21,18 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
21
21
  @sets = sets
22
22
  end
23
23
 
24
+ ##
25
+ # When +allow_prerelease+ is set to +true+ prereleases gems are allowed to
26
+ # match dependencies.
27
+
28
+ def prerelease= allow_prerelease
29
+ super
30
+
31
+ sets.each do |set|
32
+ set.prerelease = allow_prerelease
33
+ end
34
+ end
35
+
24
36
  ##
25
37
  # Sets the remote network access for all composed sets.
26
38
 
@@ -83,8 +83,8 @@ class Gem::Resolver::Conflict
83
83
 
84
84
  explanation % [
85
85
  activated, requirement,
86
- request_path(@activated).reverse.join(" depends on\n "),
87
- request_path(@failed_dep).reverse.join(" depends on\n "),
86
+ request_path(@activated).reverse.join(", depends on\n "),
87
+ request_path(@failed_dep).reverse.join(", depends on\n "),
88
88
  matching,
89
89
  ]
90
90
  end
@@ -47,8 +47,8 @@ class Gem::Resolver::DependencyRequest
47
47
  # NOTE: #match? only matches prerelease versions when #dependency is a
48
48
  # prerelease dependency.
49
49
 
50
- def match? spec
51
- @dependency.match? spec
50
+ def match? spec, allow_prerelease = false
51
+ @dependency.match? spec, nil, allow_prerelease
52
52
  end
53
53
 
54
54
  ##
@@ -43,7 +43,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
43
43
  name = req.dependency.name
44
44
 
45
45
  @all[name].each do |uri, n|
46
- if req.dependency.match? n then
46
+ if req.match? n, @prerelease then
47
47
  res << Gem::Resolver::IndexSpecification.new(
48
48
  self, n.name, n.version, uri, n.platform)
49
49
  end
@@ -157,6 +157,12 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
157
157
  @remote_set.prefetch(reqs)
158
158
  end
159
159
 
160
+ def prerelease= allow_prerelease
161
+ super
162
+
163
+ @remote_set.prerelease = allow_prerelease
164
+ end
165
+
160
166
  def inspect # :nodoc:
161
167
  always_install = @always_install.map { |s| s.full_name }
162
168
 
@@ -67,6 +67,10 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
67
67
  # A specification constructed from the lockfile is returned
68
68
 
69
69
  def spec
70
+ @spec ||= Gem::Specification.find { |spec|
71
+ spec.name == @name and spec.version == @version
72
+ }
73
+
70
74
  @spec ||= Gem::Specification.new do |s|
71
75
  s.name = @name
72
76
  s.version = @version
@@ -14,9 +14,15 @@ class Gem::Resolver::Set
14
14
 
15
15
  attr_accessor :errors
16
16
 
17
+ ##
18
+ # When true, allows matching of requests to prerelease gems.
19
+
20
+ attr_accessor :prerelease
21
+
17
22
  def initialize # :nodoc:
18
- @remote = true
19
- @errors = []
23
+ @prerelease = false
24
+ @remote = true
25
+ @errors = []
20
26
  end
21
27
 
22
28
  ##
@@ -43,6 +43,8 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
43
43
 
44
44
  @specs[spec.name] = spec
45
45
  @directories[spec] = directory
46
+
47
+ spec
46
48
  end
47
49
 
48
50
  ##
@@ -78,6 +78,8 @@ class Gem::Source
78
78
  # Returns a Set that can fetch specifications from this source.
79
79
 
80
80
  def dependency_resolver_set # :nodoc:
81
+ return Gem::Resolver::IndexSet.new self if 'file' == api_uri.scheme
82
+
81
83
  bundler_api_uri = api_uri + './api/v1/dependencies'
82
84
 
83
85
  begin
@@ -51,7 +51,7 @@ class Gem::Source::Git < Gem::Source
51
51
  # will be checked out when the gem is installed.
52
52
 
53
53
  def initialize name, repository, reference, submodules = false
54
- super(nil)
54
+ super repository
55
55
 
56
56
  @name = name
57
57
  @repository = repository
@@ -178,9 +178,17 @@ class Gem::Source::Git < Gem::Source
178
178
  # Converts the git reference for the repository into a commit hash.
179
179
 
180
180
  def rev_parse # :nodoc:
181
+ hash = nil
182
+
181
183
  Dir.chdir repo_cache_dir do
182
- Gem::Util.popen(@git, 'rev-parse', @reference).strip
184
+ hash = Gem::Util.popen(@git, 'rev-parse', @reference).strip
183
185
  end
186
+
187
+ raise Gem::Exception,
188
+ "unable to find reference #{@reference} in #{@repository}" unless
189
+ $?.success?
190
+
191
+ hash
184
192
  end
185
193
 
186
194
  ##
@@ -1421,7 +1421,10 @@ class Gem::Specification < Gem::BasicSpecification
1421
1421
 
1422
1422
  def build_args
1423
1423
  if File.exist? build_info_file
1424
- File.readlines(build_info_file).map { |x| x.strip }
1424
+ build_info = File.readlines build_info_file
1425
+ build_info = build_info.map { |x| x.strip }
1426
+ build_info.delete ""
1427
+ build_info
1425
1428
  else
1426
1429
  []
1427
1430
  end
@@ -1449,11 +1452,13 @@ class Gem::Specification < Gem::BasicSpecification
1449
1452
  require 'rubygems/ext'
1450
1453
  require 'rubygems/user_interaction'
1451
1454
 
1452
- Gem::DefaultUserInteraction.use_ui Gem::SilentUI.new do
1455
+ ui = Gem::SilentUI.new
1456
+ Gem::DefaultUserInteraction.use_ui ui do
1453
1457
  builder = Gem::Ext::Builder.new self
1454
1458
  builder.build_extensions
1455
1459
  end
1456
1460
  ensure
1461
+ ui.close if ui
1457
1462
  Gem::Specification.unresolved_deps.replace unresolved_deps
1458
1463
  end
1459
1464
  end
@@ -2653,7 +2658,8 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
2653
2658
  dep.requirement.requirements.any? do |op, version|
2654
2659
  op == '~>' and
2655
2660
  not version.prerelease? and
2656
- version.segments.length > 2
2661
+ version.segments.length > 2 and
2662
+ version.segments.first != 0
2657
2663
  end
2658
2664
 
2659
2665
  if overly_strict then
@@ -154,8 +154,13 @@ class Gem::StubSpecification < Gem::BasicSpecification
154
154
  # The full Gem::Specification for this gem, loaded from evalling its gemspec
155
155
 
156
156
  def to_spec
157
+ @spec ||= Gem.loaded_specs.values.find { |spec|
158
+ spec.name == @name and spec.version == @version
159
+ }
160
+
157
161
  @spec ||= Gem::Specification.load(loaded_from)
158
162
  @spec.ignored = @ignored if instance_variable_defined? :@ignored
163
+
159
164
  @spec
160
165
  end
161
166
 
@@ -1305,7 +1305,7 @@ Also, a list:
1305
1305
  # Finds all gems matching +dep+ in this set.
1306
1306
 
1307
1307
  def find_all(dep)
1308
- @specs.find_all { |s| dep.match? s }
1308
+ @specs.find_all { |s| dep.match? s, @prerelease }
1309
1309
  end
1310
1310
 
1311
1311
  ##
@@ -38,6 +38,8 @@ class Gem::FakeFetcher
38
38
  end
39
39
 
40
40
  def find_data(path)
41
+ return File.read path.path if URI === path and 'file' == path.scheme
42
+
41
43
  if URI === path and "URI::#{path.scheme.upcase}" != path.class.name then
42
44
  raise ArgumentError,
43
45
  "mismatch for scheme #{path.scheme} and class #{path.class}"
@@ -386,9 +386,13 @@ class Gem::StreamUI
386
386
  # handlers that might have been defined.
387
387
 
388
388
  def terminate_interaction(status = 0)
389
+ close
389
390
  raise Gem::SystemExitException, status
390
391
  end
391
392
 
393
+ def close
394
+ end
395
+
392
396
  ##
393
397
  # Return a progress reporter object chosen from the current verbosity.
394
398
 
@@ -691,6 +695,12 @@ class Gem::SilentUI < Gem::StreamUI
691
695
  super reader, writer, writer, false
692
696
  end
693
697
 
698
+ def close
699
+ super
700
+ @ins.close
701
+ @outs.close
702
+ end
703
+
694
704
  def download_reporter(*args) # :nodoc:
695
705
  SilentDownloadReporter.new(@outs, *args)
696
706
  end
@@ -66,15 +66,26 @@ module Gem::Util
66
66
  end
67
67
  end
68
68
 
69
+ NULL_DEVICE = defined?(IO::NULL) ? IO::NULL : Gem.win_platform? ? 'NUL' : '/dev/null'
70
+
69
71
  ##
70
72
  # Invokes system, but silences all output.
71
73
 
72
74
  def self.silent_system *command
75
+ opt = {:out => NULL_DEVICE, :err => [:child, :out]}
76
+ if Hash === command.last
77
+ opt.update(command.last)
78
+ cmds = command[0...-1]
79
+ else
80
+ cmds = command.dup
81
+ end
82
+ return system(*(cmds << opt))
83
+ rescue TypeError
73
84
  require 'thread'
74
85
 
75
86
  @silent_mutex ||= Mutex.new
76
87
 
77
- null_device = Gem.win_platform? ? 'NUL' : '/dev/null'
88
+ null_device = NULL_DEVICE
78
89
 
79
90
  @silent_mutex.synchronize do
80
91
  begin
@@ -88,6 +99,8 @@ module Gem::Util
88
99
  ensure
89
100
  STDOUT.reopen stdout
90
101
  STDERR.reopen stderr
102
+ stdout.close
103
+ stderr.close
91
104
  end
92
105
  end
93
106
  end
@@ -77,10 +77,10 @@ class TestGemCommandsSetupCommand < Gem::TestCase
77
77
 
78
78
  def test_show_release_notes
79
79
  @default_external = nil
80
- capture_io do
81
- @default_external, Encoding.default_external =
82
- Encoding.default_external, Encoding::US_ASCII
83
- end if Object.const_defined? :Encoding
80
+ if Object.const_defined? :Encoding
81
+ @default_external = @ui.outs.external_encoding
82
+ @ui.outs.set_encoding Encoding::US_ASCII
83
+ end
84
84
 
85
85
  @cmd.options[:previous_version] = Gem::Version.new '2.0.2'
86
86
 
@@ -127,11 +127,9 @@ class TestGemCommandsSetupCommand < Gem::TestCase
127
127
  output = @ui.output
128
128
  output.force_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
129
129
 
130
- assert_equal expected, @ui.output
130
+ assert_equal expected, output
131
131
  ensure
132
- capture_io do
133
- Encoding.default_external = @default_external
134
- end if @default_external
132
+ @ui.outs.set_encoding @default_external if @default_external
135
133
  end
136
134
 
137
135
  end
@@ -256,7 +256,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
256
256
  WARNING: Use your OS package manager to uninstall vendor gems
257
257
  EXPECTED
258
258
 
259
- assert_equal expected, @ui.error
259
+ assert_match expected, @ui.error
260
260
  end
261
261
 
262
262
  def test_handle_options_vendor_missing
@@ -485,6 +485,34 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
485
485
  assert_equal expected, @cmd.options
486
486
  end
487
487
 
488
+ def test_update_gem_prerelease
489
+ spec_fetcher do |fetcher|
490
+ fetcher.spec 'a', '1.a'
491
+ fetcher.gem 'a', '1.b'
492
+ end
493
+
494
+ @cmd.update_gem 'a', Gem::Requirement.new('= 1.b')
495
+
496
+ refute_empty @cmd.updated
497
+
498
+ assert @cmd.installer.instance_variable_get :@prerelease
499
+ end
500
+
501
+ def test_update_gem_unresolved_dependency
502
+ spec_fetcher do |fetcher|
503
+ fetcher.spec 'a', 1
504
+ fetcher.gem 'a', 2 do |s|
505
+ s.add_dependency 'b', '>= 2'
506
+ end
507
+
508
+ fetcher.spec 'b', 1
509
+ end
510
+
511
+ @cmd.update_gem 'a'
512
+
513
+ assert_empty @cmd.updated
514
+ end
515
+
488
516
  def test_update_rubygems_arguments
489
517
  @cmd.options[:system] = true
490
518
 
@@ -153,6 +153,33 @@ class TestGemDependency < Gem::TestCase
153
153
  assert c_dep.match? c_tup
154
154
  end
155
155
 
156
+ def test_match_eh_allow_prerelease
157
+ a_dep = dep 'a'
158
+
159
+ a_tup = Gem::NameTuple.new 'a', 1
160
+ b_tup = Gem::NameTuple.new 'b', 2
161
+ c_tup = Gem::NameTuple.new 'c', '2.a'
162
+
163
+ assert a_dep.match? a_tup, nil, true
164
+ refute a_dep.match? b_tup, nil, true
165
+
166
+ b_dep = dep 'b', '>= 3'
167
+
168
+ refute b_dep.match? b_tup, nil, true
169
+
170
+ c_dep = dep 'c', '>= 1'
171
+
172
+ assert c_dep.match? c_tup, nil, true
173
+
174
+ c_dep = dep 'c'
175
+
176
+ assert c_dep.match? c_tup, nil, true
177
+
178
+ c_dep = dep 'c', '2.a'
179
+
180
+ assert c_dep.match? c_tup, nil, true
181
+ end
182
+
156
183
  def test_match_eh_specification
157
184
  a_dep = dep 'a'
158
185