rubygems-update 2.0.0.preview2.2 → 2.0.0.rc.1

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.

@@ -142,7 +142,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
142
142
 
143
143
  gems_to_update = which_to_update hig, options[:args], :system
144
144
  name, up_ver = gems_to_update.first
145
- current_ver = Gem::Version.new Gem::VERSION
145
+ current_ver = Gem.rubygems_version
146
146
 
147
147
  target = if options[:system] == true then
148
148
  up_ver
@@ -10,14 +10,14 @@ class Gem::Dependency
10
10
  #--
11
11
  # When this list is updated, be sure to change
12
12
  # Gem::Specification::CURRENT_SPECIFICATION_VERSION as well.
13
-
13
+ #
14
14
  # REFACTOR: This type of constant, TYPES, indicates we might want
15
- # two classes, used via inheretance or duck typing.
15
+ # two classes, used via inheritance or duck typing.
16
16
 
17
17
  TYPES = [
18
- :development,
19
- :runtime,
20
- ]
18
+ :development,
19
+ :runtime,
20
+ ]
21
21
 
22
22
  ##
23
23
  # Dependency name or regular expression.
@@ -0,0 +1,125 @@
1
+ require 'rubygems'
2
+ require 'rubygems/user_interaction'
3
+ require 'pathname'
4
+
5
+ ##
6
+ # Cleans up after a partially-failed uninstall or for an invalid
7
+ # Gem::Specification.
8
+ #
9
+ # If a specification was removed by hand this will remove any remaining files.
10
+ #
11
+ # If a corrupt specification was installed this will clean up warnings by
12
+ # removing the bogus specification.
13
+
14
+ class Gem::Doctor
15
+
16
+ include Gem::UserInteraction
17
+
18
+ ##
19
+ # Maps a gem subdirectory to the files that are expected to exist in the
20
+ # subdirectory.
21
+
22
+ REPOSITORY_EXTENSION_MAP = [ # :nodoc:
23
+ ['specifications', '.gemspec'],
24
+ ['build_info', '.info'],
25
+ ['cache', '.gem'],
26
+ ['doc', ''],
27
+ ['gems', ''],
28
+ ]
29
+
30
+ raise 'Update REPOSITORY_EXTENSION_MAP' unless
31
+ Gem::REPOSITORY_SUBDIRECTORIES.sort ==
32
+ REPOSITORY_EXTENSION_MAP.map { |(k,_)| k }.sort
33
+
34
+ ##
35
+ # Creates a new Gem::Doctor that will clean up +gem_repository+. Only one
36
+ # gem repository may be cleaned at a time.
37
+ #
38
+ # If +dry_run+ is true no files or directories will be removed.
39
+
40
+ def initialize gem_repository, dry_run = false
41
+ @gem_repository = Pathname(gem_repository)
42
+ @dry_run = dry_run
43
+
44
+ @installed_specs = nil
45
+ end
46
+
47
+ ##
48
+ # Specs installed in this gem repository
49
+
50
+ def installed_specs # :nodoc:
51
+ @installed_specs ||= Gem::Specification.map { |s| s.full_name }
52
+ end
53
+
54
+ ##
55
+ # Are we doctoring a gem repository?
56
+
57
+ def gem_repository?
58
+ not installed_specs.empty?
59
+ end
60
+
61
+ ##
62
+ # Cleans up uninstalled files and invalid gem specifications
63
+
64
+ def doctor
65
+ @orig_home = Gem.dir
66
+ @orig_path = Gem.path
67
+
68
+ say "Checking #{@gem_repository}"
69
+
70
+ Gem.use_paths @gem_repository.to_s
71
+
72
+ unless gem_repository? then
73
+ say 'This directory does not appear to be a RubyGems repository, ' +
74
+ 'skipping'
75
+ say
76
+ return
77
+ end
78
+
79
+ doctor_children
80
+
81
+ say
82
+ ensure
83
+ Gem.use_paths @orig_home, *@orig_path
84
+ end
85
+
86
+ ##
87
+ # Cleans up children of this gem repository
88
+
89
+ def doctor_children # :nodoc:
90
+ REPOSITORY_EXTENSION_MAP.each do |sub_directory, extension|
91
+ doctor_child sub_directory, extension
92
+ end
93
+ end
94
+
95
+ ##
96
+ # Removes files in +sub_directory+ with +extension+
97
+
98
+ def doctor_child sub_directory, extension # :nodoc:
99
+ directory = @gem_repository + sub_directory
100
+
101
+ directory.children.sort.each do |child|
102
+ next unless child.exist?
103
+
104
+ basename = child.basename(extension).to_s
105
+ next if installed_specs.include? basename
106
+ next if /^rubygems-\d/ =~ basename
107
+ next if 'specifications' == sub_directory and 'default' == basename
108
+
109
+ type = child.directory? ? 'directory' : 'file'
110
+
111
+ action = if @dry_run then
112
+ 'Extra'
113
+ else
114
+ child.rmtree
115
+ 'Removed'
116
+ end
117
+
118
+ say "#{action} #{type} #{sub_directory}/#{child.basename}"
119
+ end
120
+ rescue Errno::ENOENT
121
+ # ignore
122
+ end
123
+
124
+ end
125
+
@@ -202,47 +202,24 @@ class Gem::Installer
202
202
  # specifications/<gem-version>.gemspec #=> the Gem::Specification
203
203
 
204
204
  def install
205
- verify_gem_home(options[:unpack])
206
-
207
- # If we're forcing the install then disable security unless the security
208
- # policy says that we only install signed gems.
209
- @security_policy = nil if @force and @security_policy and
210
- not @security_policy.only_signed
211
-
212
- unless @force
213
- ensure_required_ruby_version_met
214
- ensure_required_rubygems_version_met
215
- ensure_dependencies_met unless @ignore_dependencies
216
- end
205
+ pre_install_checks
217
206
 
218
207
  run_pre_install_hooks
219
208
 
220
- Gem.ensure_gem_subdirectories gem_home
221
-
222
209
  # Completely remove any previous gem files
223
- FileUtils.rm_rf(gem_dir)
210
+ FileUtils.rm_rf gem_dir
224
211
 
225
212
  FileUtils.mkdir_p gem_dir
226
213
 
227
214
  extract_files
228
- build_extensions
229
215
 
216
+ build_extensions
217
+ write_build_info_file
230
218
  run_post_build_hooks
231
219
 
232
220
  generate_bin
233
221
  write_spec
234
-
235
- unless @build_args.empty?
236
- File.open spec.build_info_file, "w" do |f|
237
- @build_args.each { |a| f.puts a }
238
- end
239
- end
240
-
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")
244
-
245
- FileUtils.cp gem, cache_file unless File.exist? cache_file
222
+ write_cache_file
246
223
 
247
224
  say spec.post_install_message unless spec.post_install_message.nil?
248
225
 
@@ -255,7 +232,7 @@ class Gem::Installer
255
232
  spec
256
233
 
257
234
  # 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.
235
+ # move this rescue to around the code that actually might raise it.
259
236
  rescue Zlib::GzipFile::Error
260
237
  raise Gem::InstallError, "gzip error installing #{gem}"
261
238
  end
@@ -506,6 +483,22 @@ class Gem::Installer
506
483
  end
507
484
  end
508
485
 
486
+ ##
487
+ # Ensures the Gem::Specification written out for this gem is loadable upon
488
+ # installation.
489
+
490
+ def ensure_loadable_spec
491
+ ruby = spec.to_ruby_for_cache
492
+ ruby.untaint
493
+
494
+ begin
495
+ eval ruby
496
+ rescue StandardError, SyntaxError => e
497
+ raise Gem::InstallError,
498
+ "The specification for #{spec.full_name} is corrupt (#{e.class})"
499
+ end
500
+ end
501
+
509
502
  # DOC: Missing docs or :nodoc:.
510
503
  def ensure_required_ruby_version_met
511
504
  if rrv = spec.required_ruby_version then
@@ -736,5 +729,59 @@ EOF
736
729
  def dir
737
730
  gem_dir.to_s
738
731
  end
732
+
733
+ ##
734
+ # Performs various checks before installing the gem such as the install
735
+ # repository is writable and its directories exist, required ruby and
736
+ # rubygems versions are met and that dependencies are installed.
737
+ #
738
+ # Version and dependency checks are skipped if this install is forced.
739
+ #
740
+ # The dependent check will be skipped this install is ignoring dependencies.
741
+
742
+ def pre_install_checks
743
+ verify_gem_home options[:unpack]
744
+
745
+ # If we're forcing the install then disable security unless the security
746
+ # policy says that we only install signed gems.
747
+ @security_policy = nil if
748
+ @force and @security_policy and not @security_policy.only_signed
749
+
750
+ ensure_loadable_spec
751
+
752
+ Gem.ensure_gem_subdirectories gem_home
753
+
754
+ return true if @force
755
+
756
+ ensure_required_ruby_version_met
757
+ ensure_required_rubygems_version_met
758
+ ensure_dependencies_met unless @ignore_dependencies
759
+
760
+ true
761
+ end
762
+
763
+ ##
764
+ # Writes the file containing the arguments for building this gem's
765
+ # extensions.
766
+
767
+ def write_build_info_file
768
+ return if @build_args.empty?
769
+
770
+ open spec.build_info_file, 'w' do |io|
771
+ @build_args.each do |arg|
772
+ io.puts arg
773
+ end
774
+ end
775
+ end
776
+
777
+ ##
778
+ # Writes the .gem file to the cache directory
779
+
780
+ def write_cache_file
781
+ cache_file = File.join gem_home, 'cache', spec.file_name
782
+
783
+ FileUtils.cp @gem, cache_file unless File.exist? cache_file
784
+ end
785
+
739
786
  end
740
787
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #--
2
3
  # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
3
4
  # All rights reserved.
@@ -621,7 +622,6 @@ class Gem::Specification
621
622
  File.join(Gem.default_dir, "specifications", "default")
622
623
  end
623
624
 
624
- private
625
625
  def each_spec(search_dirs) # :nodoc:
626
626
  search_dirs.each { |dir|
627
627
  Dir[File.join(dir, "*.gemspec")].each { |path|
@@ -2048,7 +2048,9 @@ class Gem::Specification
2048
2048
  when Numeric then obj.inspect
2049
2049
  when true, false, nil then obj.inspect
2050
2050
  when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
2051
- when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})"
2051
+ when Gem::Requirement then
2052
+ list = obj.as_list
2053
+ "Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})"
2052
2054
  else raise Gem::Exception, "ruby_code case not handled: #{obj.class}"
2053
2055
  end
2054
2056
  end
@@ -465,6 +465,19 @@ class Gem::TestCase < MiniTest::Unit::TestCase
465
465
  Gem.searcher = nil
466
466
  end
467
467
 
468
+ ##
469
+ # Installs the provided default specs including writing the spec file
470
+
471
+ def install_default_gems(*specs)
472
+ install_default_specs(*specs)
473
+
474
+ specs.each do |spec|
475
+ open spec.loaded_from, 'w' do |io|
476
+ io.write spec.to_ruby_for_cache
477
+ end
478
+ end
479
+ end
480
+
468
481
  ##
469
482
  # Install the provided default specs
470
483
 
@@ -572,7 +585,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
572
585
  block = proc do |s|
573
586
  # Since Hash#each is unordered in 1.8, sort
574
587
  # the keys and iterate that way so the tests are
575
- # deteriminstic on all implementations.
588
+ # deterministic on all implementations.
576
589
  deps.keys.sort.each do |n|
577
590
  s.add_dependency n, (deps[n] || '>= 0')
578
591
  end
@@ -72,7 +72,19 @@ class Gem::Uninstaller
72
72
  # directory, and the cached .gem file.
73
73
 
74
74
  def uninstall
75
- list = Gem::Specification.find_all_by_name(@gem, @version)
75
+ dependency = Gem::Dependency.new @gem, @version
76
+
77
+ list = []
78
+
79
+ dirs =
80
+ Gem::Specification.dirs +
81
+ [Gem::Specification.default_specifications_dir]
82
+
83
+ Gem::Specification.each_spec dirs do |spec|
84
+ next unless dependency.matches_spec? spec
85
+
86
+ list << spec
87
+ end
76
88
 
77
89
  default_specs, list = list.partition do |spec|
78
90
  spec.default_gem?
@@ -80,7 +92,7 @@ class Gem::Uninstaller
80
92
 
81
93
  list, other_repo_specs = list.partition do |spec|
82
94
  @gem_home == spec.base_dir or
83
- (@user_install and spec.base_dir == Gem.user_dir)
95
+ (@user_install and spec.base_dir == Gem.user_dir)
84
96
  end
85
97
 
86
98
  if list.empty? then
@@ -58,13 +58,11 @@ class Gem::Validator
58
58
  public
59
59
 
60
60
  ErrorData = Struct.new :path, :problem do
61
-
62
61
  def <=> other
63
62
  return nil unless self.class === other
64
63
 
65
64
  [path, problem] <=> [other.path, other.problem]
66
65
  end
67
-
68
66
  end
69
67
 
70
68
  ##
@@ -121,7 +119,6 @@ class Gem::Validator
121
119
  File.readable? File.join(gem_directory, file_name)
122
120
  }
123
121
 
124
- unreadable.map! { |entry, _| entry['path'] }
125
122
  unreadable.sort.each do |path|
126
123
  errors[gem_name][path] = "Unreadable file"
127
124
  end
@@ -153,7 +150,9 @@ class Gem::Validator
153
150
  end
154
151
 
155
152
  errors.each do |name, subhash|
156
- errors[name] = subhash.map { |path, msg| ErrorData.new(path, msg) }.sort
153
+ errors[name] = subhash.map do |path, msg|
154
+ ErrorData.new path, msg
155
+ end.sort
157
156
  end
158
157
 
159
158
  errors
@@ -774,6 +774,45 @@ class TestGem < Gem::TestCase
774
774
  assert_equal cwd, $LOAD_PATH.shift
775
775
  end
776
776
 
777
+ def test_self_latest_spec_for
778
+ a1 = quick_spec 'a', 1
779
+ a2 = quick_spec 'a', 2
780
+ a3a = quick_spec 'a', '3.a'
781
+
782
+ util_setup_fake_fetcher
783
+ util_setup_spec_fetcher a1, a2, a3a
784
+
785
+ spec = Gem.latest_spec_for 'a'
786
+
787
+ assert_equal a2, spec
788
+ end
789
+
790
+ def test_self_latest_rubygems_version
791
+ r1 = quick_spec 'rubygems-update', '1.8.23'
792
+ r2 = quick_spec 'rubygems-update', '1.8.24'
793
+ r3 = quick_spec 'rubygems-update', '2.0.0.preview3'
794
+
795
+ util_setup_fake_fetcher
796
+ util_setup_spec_fetcher r1, r2, r3
797
+
798
+ version = Gem.latest_rubygems_version
799
+
800
+ assert_equal Gem::Version.new('1.8.24'), version
801
+ end
802
+
803
+ def test_self_latest_version_for
804
+ a1 = quick_spec 'a', 1
805
+ a2 = quick_spec 'a', 2
806
+ a3a = quick_spec 'a', '3.a'
807
+
808
+ util_setup_fake_fetcher
809
+ util_setup_spec_fetcher a1, a2, a3a
810
+
811
+ version = Gem.latest_version_for 'a'
812
+
813
+ assert_equal Gem::Version.new(2), version
814
+ end
815
+
777
816
  def test_self_loaded_specs
778
817
  foo = quick_spec 'foo'
779
818
  install_gem foo