[前][次][番号順一覧][スレッド一覧]

ruby-changes:26410

From: drbrain <ko1@a...>
Date: Wed, 19 Dec 2012 16:19:21 +0900 (JST)
Subject: [ruby-changes:26410] drbrain:r38461 (trunk): * lib/rubygems/commands/query_command.rb: Refactored to improve

drbrain	2012-12-19 16:19:10 +0900 (Wed, 19 Dec 2012)

  New Revision: 38461

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38461

  Log:
    * lib/rubygems/commands/query_command.rb:  Refactored to improve
      maintainability.
    * test/rubygems/test_gem_commands_query_command.rb:  Note default gems
      in gem list details.
    
    * lib/rubygems/uninstaller.rb:  Detect all gems for uninstallation.
      This allows duplicate installs of default gems to be removed.
    * lib/rubygems/specification.rb:  Allow use of ::each_spec.
    * lib/rubygems/test_case.rb:  Added install_default_gems.
    * test/rubygems/test_gem_commands_uninstall_command.rb:  Moved test
      down to the uninstaller tests.
    * test/rubygems/test_gem_uninstaller.rb:  Test for uninstallation of
      default gems and duplicate default gems.

  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/commands/query_command.rb
    trunk/lib/rubygems/specification.rb
    trunk/lib/rubygems/test_case.rb
    trunk/lib/rubygems/uninstaller.rb
    trunk/test/rubygems/test_gem_commands_query_command.rb
    trunk/test/rubygems/test_gem_commands_uninstall_command.rb
    trunk/test/rubygems/test_gem_uninstaller.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38460)
+++ ChangeLog	(revision 38461)
@@ -1,3 +1,19 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Dec 19 16:18:22 2012  Eric Hodel  <drbrain@s...>
+
+	* lib/rubygems/commands/query_command.rb:  Refactored to improve
+	  maintainability.
+	* test/rubygems/test_gem_commands_query_command.rb:  Note default gems
+	  in gem list details.
+
+	* lib/rubygems/uninstaller.rb:  Detect all gems for uninstallation.
+	  This allows duplicate installs of default gems to be removed.
+	* lib/rubygems/specification.rb:  Allow use of ::each_spec.
+	* lib/rubygems/test_case.rb:  Added install_default_gems.
+	* test/rubygems/test_gem_commands_uninstall_command.rb:  Moved test
+	  down to the uninstaller tests.
+	* test/rubygems/test_gem_uninstaller.rb:  Test for uninstallation of
+	  default gems and duplicate default gems.
+
 Wed Dec 19 15:23:50 2012  Eric Hodel  <drbrain@s...>
 
 	* doc/syntax/methods.rdoc:  Add () around keyword arguments example for
Index: lib/rubygems/specification.rb
===================================================================
--- lib/rubygems/specification.rb	(revision 38460)
+++ lib/rubygems/specification.rb	(revision 38461)
@@ -622,7 +622,6 @@ class Gem::Specification https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L622
       File.join(Gem.default_dir, "specifications", "default")
     end
 
-    private
     def each_spec(search_dirs) # :nodoc:
       search_dirs.each { |dir|
         Dir[File.join(dir, "*.gemspec")].each { |path|
Index: lib/rubygems/commands/query_command.rb
===================================================================
--- lib/rubygems/commands/query_command.rb	(revision 38460)
+++ lib/rubygems/commands/query_command.rb	(revision 38461)
@@ -162,12 +162,18 @@ class Gem::Commands::QueryCommand < Gem: https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/query_command.rb#L162
       n.downcase
     end
 
+    output_versions output, versions
+
+    say output.join(options[:details] ? "\n\n" : "\n")
+  end
+
+  def output_versions output, versions
     versions.each do |gem_name, matching_tuples|
       matching_tuples = matching_tuples.sort_by { |n,_| n.version }.reverse
 
       platforms = Hash.new { |h,version| h[version] = [] }
 
-      matching_tuples.map do |n,_|
+      matching_tuples.each do |n, _|
         platforms[n.version] << n.platform if n.platform
       end
 
@@ -182,97 +188,125 @@ class Gem::Commands::QueryCommand < Gem: https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/query_command.rb#L188
         end
       end
 
-      entry = gem_name.dup
+      output << make_entry(matching_tuples, platforms)
+    end
+  end
 
-      if options[:versions] then
-        list = if platforms.empty? or options[:details] then
-                 matching_tuples.map { |n,_| n.version }.uniq
-               else
-                 platforms.sort.reverse.map do |version, pls|
-                   if pls == [Gem::Platform::RUBY] then
-                     version
-                   else
-                     ruby = pls.delete Gem::Platform::RUBY
-                     platform_list = [ruby, *pls.sort].compact
-                     "#{version} #{platform_list.join ' '}"
-                   end
-                 end
-               end.join ', '
+  def entry_details entry, spec, specs, platforms
+    return unless options[:details]
 
-        entry << " (#{list})"
-      end
+    entry << "\n"
 
-      if options[:details] then
-        detail_tuple = matching_tuples.first
+    spec_platforms   entry, platforms
+    spec_authors     entry, spec
+    spec_homepage    entry, spec
+    spec_license     entry, spec
+    spec_loaded_from entry, spec, specs
+    spec_summary     entry, spec
+  end
 
-        spec = detail_tuple.last
+  def entry_versions entry, name_tuples, platforms
+    return unless options[:versions]
 
-        unless spec.kind_of? Gem::Specification
-          spec = spec.fetch_spec detail_tuple.first
+    list =
+      if platforms.empty? or options[:details] then
+        name_tuples.map { |n| n.version }.uniq
+      else
+        platforms.sort.reverse.map do |version, pls|
+          if pls == [Gem::Platform::RUBY] then
+            version
+          else
+            ruby = pls.delete Gem::Platform::RUBY
+            platform_list = [ruby, *pls.sort].compact
+            "#{version} #{platform_list.join ' '}"
+          end
         end
+      end
 
-        entry << "\n"
+    entry << " (#{list.join ', '})"
+  end
 
-        non_ruby = platforms.any? do |_, pls|
-          pls.any? { |pl| pl != Gem::Platform::RUBY }
-        end
+  def make_entry entry_tuples, platforms
+    detail_tuple = entry_tuples.first
+    name_tuple, latest_spec = detail_tuple
 
-        if non_ruby then
-          if platforms.length == 1 then
-            title = platforms.values.length == 1 ? 'Platform' : 'Platforms'
-            entry << "    #{title}: #{platforms.values.sort.join ', '}\n"
-          else
-            entry << "    Platforms:\n"
-            platforms.sort_by do |version,|
-              version
-            end.each do |version, pls|
-              label = "        #{version}: "
-              data = format_text pls.sort.join(', '), 68, label.length
-              data[0, label.length] = label
-              entry << data << "\n"
-            end
-          end
-        end
+    latest_spec = latest_spec.fetch_spec name_tuple unless
+      Gem::Specification === latest_spec
 
-        authors = "Author#{spec.authors.length > 1 ? 's' : ''}: "
-        authors << spec.authors.join(', ')
-        entry << format_text(authors, 68, 4)
-
-        if spec.rubyforge_project and not spec.rubyforge_project.empty? then
-          rubyforge = "Rubyforge: http://rubyforge.org/projects/#{spec.rubyforge_project}"
-          entry << "\n" << format_text(rubyforge, 68, 4)
-        end
+    name_tuples, specs = entry_tuples.flatten.partition do |item|
+      Gem::NameTuple === item
+    end
 
-        if spec.homepage and not spec.homepage.empty? then
-          entry << "\n" << format_text("Homepage: #{spec.homepage}", 68, 4)
-        end
+    entry = [latest_spec.name]
 
-        if spec.license and not spec.license.empty? then
-          licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: "
-          licenses << spec.licenses.join(', ')
-          entry << "\n" << format_text(licenses, 68, 4)
-        end
+    entry_versions entry, name_tuples, platforms
+    entry_details  entry, latest_spec, specs, platforms
 
-        if spec.loaded_from then
-          if matching_tuples.length == 1 then
-            loaded_from = File.dirname File.dirname(spec.loaded_from)
-            entry << "\n" << "    Installed at: #{loaded_from}"
-          else
-            label = 'Installed at'
-            matching_tuples.each do |n,s|
-              loaded_from = File.dirname File.dirname(s.loaded_from)
-              entry << "\n" << "    #{label} (#{n.version}): #{loaded_from}"
-              label = ' ' * label.length
-            end
-          end
-        end
+    entry.join
+  end
+
+  def spec_authors entry, spec
+    authors = "Author#{spec.authors.length > 1 ? 's' : ''}: "
+    authors << spec.authors.join(', ')
+    entry << format_text(authors, 68, 4)
+  end
+
+  def spec_homepage entry, spec
+    return if spec.homepage.nil? or spec.homepage.empty?
+
+    entry << "\n" << format_text("Homepage: #{spec.homepage}", 68, 4)
+  end
+
+  def spec_license entry, spec
+    return if spec.license.nil? or spec.license.empty?
+
+    licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: "
+    licenses << spec.licenses.join(', ')
+    entry << "\n" << format_text(licenses, 68, 4)
+  end
 
-        entry << "\n\n" << format_text(spec.summary, 68, 4)
+  def spec_loaded_from entry, spec, specs
+    return unless spec.loaded_from
+
+    if specs.length == 1 then
+      default = spec.default_gem? ? ' (default)' : nil
+      entry << "\n" << "    Installed at#{default}: #{spec.base_dir}"
+    else
+      label = 'Installed at'
+      specs.each do |s|
+        version = s.version.to_s
+        version << ', default' if s.default_gem?
+        entry << "\n" << "    #{label} (#{version}): #{s.base_dir}"
+        label = ' ' * label.length
       end
-      output << entry
     end
+  end
 
-    say output.join(options[:details] ? "\n\n" : "\n")
+  def spec_platforms entry, platforms
+    non_ruby = platforms.any? do |_, pls|
+      pls.any? { |pl| pl != Gem::Platform::RUBY }
+    end
+
+    return unless non_ruby
+
+    if platforms.length == 1 then
+      title = platforms.values.length == 1 ? 'Platform' : 'Platforms'
+      entry << "    #{title}: #{platforms.values.sort.join ', '}\n"
+    else
+      entry << "    Platforms:\n"
+      platforms.sort_by do |version,|
+        version
+      end.each do |version, pls|
+        label = "        #{version}: "
+        data = format_text pls.sort.join(', '), 68, label.length
+        data[0, label.length] = label
+        entry << data << "\n"
+      end
+    end
+  end
+
+  def spec_summary entry, spec
+    entry << "\n\n" << format_text(spec.summary, 68, 4)
   end
 
 end
Index: lib/rubygems/uninstaller.rb
===================================================================
--- lib/rubygems/uninstaller.rb	(revision 38460)
+++ lib/rubygems/uninstaller.rb	(revision 38461)
@@ -72,7 +72,19 @@ class Gem::Uninstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/uninstaller.rb#L72
   # directory, and the cached .gem file.
 
   def uninstall
-    list = Gem::Specification.find_all_by_name(@gem, @version)
+    dependency = Gem::Dependency.new @gem, @version
+
+    list = []
+
+    dirs =
+      Gem::Specification.dirs +
+      [Gem::Specification.default_specifications_dir]
+
+    Gem::Specification.each_spec dirs do |spec|
+      next unless dependency.matches_spec? spec
+
+      list << spec
+    end
 
     default_specs, list = list.partition do |spec|
       spec.default_gem?
@@ -80,7 +92,7 @@ class Gem::Uninstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/uninstaller.rb#L92
 
     list, other_repo_specs = list.partition do |spec|
       @gem_home == spec.base_dir or
-      (@user_install and spec.base_dir == Gem.user_dir)
+        (@user_install and spec.base_dir == Gem.user_dir)
     end
 
     if list.empty? then
Index: lib/rubygems/test_case.rb
===================================================================
--- lib/rubygems/test_case.rb	(revision 38460)
+++ lib/rubygems/test_case.rb	(revision 38461)
@@ -466,6 +466,19 @@ class Gem::TestCase < MiniTest::Unit::Te https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L466
   end
 
   ##
+  # Installs the provided default specs including writing the spec file
+
+  def install_default_gems(*specs)
+    install_default_specs(*specs)
+
+    specs.each do |spec|
+      open spec.loaded_from, 'w' do |io|
+        io.write spec.to_ruby_for_cache
+      end
+    end
+  end
+
+  ##
   # Install the provided default specs
 
   def install_default_specs(*specs)
@@ -572,7 +585,7 @@ class Gem::TestCase < MiniTest::Unit::Te https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L585
       block = proc do |s|
         # Since Hash#each is unordered in 1.8, sort
         # the keys and iterate that way so the tests are
-        # deteriminstic on all implementations.
+        # deterministic on all implementations.
         deps.keys.sort.each do |n|
           s.add_dependency n, (deps[n] || '>= 0')
         end
Index: test/rubygems/test_gem_commands_uninstall_command.rb
===================================================================
--- test/rubygems/test_gem_commands_uninstall_command.rb	(revision 38460)
+++ test/rubygems/test_gem_commands_uninstall_command.rb	(revision 38461)
@@ -175,23 +175,5 @@ class TestGemCommandsUninstallCommand < https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_uninstall_command.rb#L175
     assert Gem::Specification.find_all_by_name('x').length == 0
   end
 
-  def test_execute_default_gem
-    default_gem_spec = new_default_spec("default", "2.0.0.0",
-                                        nil, "default/gem.rb")
-    install_default_specs(default_gem_spec)
-
-    ui = Gem::MockGemUi.new
-
-    @cmd.options[:args] = %w[default]
-    @cmd.options[:executables] = true
-
-    use_ui ui do
-      e = assert_raises Gem::InstallError do
-        @cmd.execute
-      end
-      assert_equal "gem \"default\" cannot be uninstalled because it is a default gem",
-                   e.message
-    end
-  end
 end
 
Index: test/rubygems/test_gem_uninstaller.rb
===================================================================
--- test/rubygems/test_gem_uninstaller.rb	(revision 38460)
+++ test/rubygems/test_gem_uninstaller.rb	(revision 38461)
@@ -172,6 +172,38 @@ class TestGemUninstaller < Gem::Installe https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_uninstaller.rb#L172
     assert_same uninstaller, @post_uninstall_hook_arg
   end
 
+  def test_uninstall_default_gem
+    spec = new_default_spec 'default', '2'
+
+    install_default_gems spec
+
+    uninstaller = Gem::Uninstaller.new spec.name, :executables => true
+
+    e = assert_raises Gem::InstallError do
+      uninstaller.uninstall
+    end
+
+    assert_equal 'gem "default" cannot be uninstalled ' +
+                 'because it is a default gem',
+                 e.message
+  end
+
+  def test_uninstall_default_gem_with_same_version
+    default_spec = new_default_spec 'default', '2'
+    install_default_gems default_spec
+
+    spec = new_spec 'default', '2'
+    install_gem spec
+
+    Gem::Specification.reset
+
+    uninstaller = Gem::Uninstaller.new spec.name, :executables => true
+
+    uninstaller.uninstall
+
+    refute_path_exists spec.gem_dir
+  end
+
   def test_uninstall_nonexistent
     uninstaller = Gem::Uninstaller.new 'bogus', :executables => true
 
@@ -265,8 +297,8 @@ class TestGemUninstaller < Gem::Installe https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_uninstaller.rb#L297
   end
 
   def test_uninstall_prompts_about_broken_deps
-    util_gem 'r', '1', 'q' => '= 1'
-    util_gem 'q', '1'
+    quick_gem 'r', '1' do |s| s.add_dependency 'q', '= 1' end
+    quick_gem 'q', '1'
 
     un = Gem::Uninstaller.new('q')
     ui = Gem::MockGemUi.new("y\n")
@@ -287,10 +319,10 @@ class TestGemUninstaller < Gem::Installe https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_uninstaller.rb#L319
   end
 
   def test_uninstall_only_lists_unsatified_deps
-    util_gem 'r', '1', 'q' => '~> 1.0'
-    util_gem 'x', '1', 'q' => '= 1.0'
-    util_gem 'q', '1.0'
-    util_gem 'q', '1.1'
+    quick_gem 'r', '1' do |s| s.add_dependency 'q', '~> 1.0' end
+    quick_gem 'x', '1' do |s| s.add_dependency 'q', '= 1.0'  end
+    quick_gem 'q', '1.0'
+    quick_gem 'q', '1.1'
 
     un = Gem::Uninstaller.new('q', :version => "1.0")
     ui = Gem::MockGemUi.new("y\n")
@@ -311,9 +343,9 @@ class TestGemUninstaller < Gem::Installe https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_uninstaller.rb#L343
   end
 
   def test_uninstall_doesnt_prompt_when_other_gem_satifies_requirement
-    util_gem 'r', '1', 'q' => '~> 1.0'
-    util_gem 'q', '1.0'
-    util_gem 'q', '1.1'
+    quick_gem 'r', '1' do |s| s.add_dependency 'q', '~> 1.0' end
+    quick_gem 'q', '1.0'
+    quick_gem 'q', '1.1'
 
     un = Gem::Uninstaller.new('q', :version => "1.0")
     ui = Gem::MockGemUi.new("y\n")
@@ -328,11 +360,8 @@ class TestGemUninstaller < Gem::Installe https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_uninstaller.rb#L360
   end
 
   def test_uninstall_doesnt_prompt_when_removing_a_dev_dep
-    util_gem('r', '1') do |s|
-      s.add_development_dependency "q", "= 1.0"
-    end
-
-    util_gem 'q', '1.0'
+    quick_gem 'r', '1' do |s| s.add_development_dependency 'q', '= 1.0' end
+    quick_gem 'q', '1.0'
 
     un = Gem::Uninstaller.new('q', :version => "1.0")
     ui = Gem::MockGemUi.new("y\n")
@@ -348,11 +377,11 @@ class TestGemUninstaller < Gem::Installe https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_uninstaller.rb#L377
 
 
   def test_uninstall_prompt_includes_dep_type
-    util_gem 'r', '1' do |s|
+    quick_gem 'r', '1' do |s|
       s.add_development_dependency 'q', '= 1'
     end
 
-    util_gem 'q', '1'
+    quick_gem 'q', '1'
 
     un = Gem::Uninstaller.new('q', :check_dev => true)
     ui = Gem::MockGemUi.new("y\n")
Index: test/rubygems/test_gem_commands_query_command.rb
===================================================================
--- test/rubygems/test_gem_commands_query_command.rb	(revision 38460)
+++ test/rubygems/test_gem_commands_query_command.rb	(revision 38461)
@@ -106,7 +106,6 @@ pl (1 i386-linux) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L106
     @a2.summary = 'This is a lot of text. ' * 4
     @a2.authors = ['Abraham Lincoln', 'Hirohito']
     @a2.homepage = 'http://a.example.com/'
-    @a2.rubyforge_project = 'rubygems'
 
     util_clear_gems
     util_setup_spec_fetcher @a1, @a2, @pl1
@@ -123,7 +122,6 @@ pl (1 i386-linux) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L122
 
 a (2)
     Authors: Abraham Lincoln, Hirohito
-    Rubyforge: http://rubyforge.org/projects/rubygems
     Homepage: http://a.example.com/
 
     This is a lot of text. This is a lot of text. This is a lot of text.
@@ -147,7 +145,6 @@ pl (1) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L145
     @a2.summary = 'This is a lot of text. ' * 4
     @a2.authors = ['Abraham Lincoln', 'Hirohito']
     @a2.homepage = 'http://a.example.com/'
-    @a2.rubyforge_project = 'rubygems'
     @a2.platform = 'universal-darwin'
 
     util_clear_gems
@@ -168,7 +165,6 @@ a (2, 1) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L165
         1: x86-linux
         2: universal-darwin
     Authors: Abraham Lincoln, Hirohito
-    Rubyforge: http://rubyforge.org/projects/rubygems
     Homepage: http://a.example.com/
 
     This is a lot of text. This is a lot of text. This is a lot of text.
@@ -355,7 +351,6 @@ pl (1 i386-linux) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L351
     @a2.summary = 'This is a lot of text. ' * 4
     @a2.authors = ['Abraham Lincoln', 'Hirohito']
     @a2.homepage = 'http://a.example.com/'
-    @a2.rubyforge_project = 'rubygems'
     @a2.platform = 'universal-darwin'
 
     util_clear_gems
@@ -380,7 +375,6 @@ a (2, 1) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L375
         1: x86-linux
         2: universal-darwin
     Authors: Abraham Lincoln, Hirohito
-    Rubyforge: http://rubyforge.org/projects/rubygems
     Homepage: http://a.example.com/
     Installed at -
                  -
@@ -400,5 +394,43 @@ pl \(1\) https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_commands_query_command.rb#L394
     assert_match expected, @ui.output
   end
 
+  def test_execute_default_details
+    default_gem_dir = Gem::Specification.default_specifications_dir
+    @a1.loaded_from =
+      File.join default_gem_dir, @a1.spec_name
+
+    @cmd.handle_options %w[-l -d]
+
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    str = @ui.output
+
+    expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (3.a, 2, 1)
+    Author: A User
+    Homepage: http://example.com
+    Installed at (3.a): #{@gemhome}
+                 (2): #{@gemhome}
+                 (1, default): #{@a1.base_dir}
+
+    this is a summary
+
+pl \(1\)
+    Platform: i386-linux
+    Author: A User
+    Homepage: http://example.com
+    Installed at: #{@gemhome}
+
+    this is a summary
+    EOF
+
+    assert_equal expected, @ui.o (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]