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

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.

@@ -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