Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

improve deprecation warning output

  • Loading branch information...
commit 0e8d1eb2be0958a8d1fadf6264a9a9b10fd4e01c 1 parent 997f71f
@alexch authored
View
3  lib/rubygems.rb
@@ -112,6 +112,7 @@ class << Gem
# * Daniel Berger -- djberg96(at)gmail.com
# * Phil Hagelberg -- technomancy(at)gmail.com
# * Ryan Davis -- ryand-ruby(at)zenspider.com
+# * Alex Chaffee -- alex(at)stinky.com
#
# (If your name is missing, PLEASE let us know!)
#
@@ -120,7 +121,7 @@ class << Gem
# -The RubyGems Team
module Gem
- VERSION = '1.8.1'
+ VERSION = '1.8.2'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
View
73 lib/rubygems/deprecate.rb
@@ -21,15 +21,48 @@
# end
module Deprecate
+
+ SKIP_DEFAULT = false
+ @skip = nil
def self.skip # :nodoc:
- @skip.nil? ? (@skip = true) : @skip
+ @skip.nil? ? SKIP_DEFAULT : @skip
end
def self.skip= v # :nodoc:
@skip = v
end
+ def self.saved_warnings # :nodoc:
+ @saved_warnings ||= []
+ end
+
+ def self.add_warning w # :nodoc:
+ warn "Warning: #{w.message} (Further warnings suppressed until exit.)\n#{w.loc}" if saved_warnings.empty?
+ unless saved_warnings.include? w
+ @saved_warnings << w
+ end
+ end
+
+ at_exit do
+ # todo: extract and test
+ unless Deprecate.saved_warnings.size == 0
+ warn Deprecate.report
+ end
+ end
+
+ def self.report
+ out = ""
+ out << "Some of your installed gems called deprecated methods. See http://blog.zenspider.com/2011/05/rubygems-18-is-coming.html for background. Use 'gem pristine --all' to fix or 'rubygems update --system 1.7.2' to downgrade.\n"
+ last_message = nil
+ warnings = @saved_warnings.sort_by{|w| w.full_name}.each do |w|
+ out << (last_message = w.message) + "\n" unless last_message == w.message
+ out << w.loc
+ out << "\n"
+ end
+ out
+ end
+
##
# Temporarily turn off warnings. Intended for tests only.
@@ -40,6 +73,24 @@ def skip_during(will_skip = true)
Deprecate.skip = original
end
+ require 'ostruct'
+ class Warning < OpenStruct
+ def message
+ [ "#{target}#{method_name} is deprecated",
+ repl == :none ? " with no replacement" : "; use #{replacement} instead.",
+ " It will be removed on or after %4d-%02d-01." % [year, month]
+ ].join
+ end
+
+ def loc
+ " called from #{location.join(":")}"
+ end
+
+ def full_name
+ "#{target}#{method_name}"
+ end
+ end
+
##
# Simple deprecation method that deprecates +name+ by wrapping it up
# in a dummy method. It warns on each call to the dummy method
@@ -51,14 +102,18 @@ def deprecate name, repl, year, month
old = "_deprecated_#{name}"
alias_method old, name
define_method name do |*args, &block| # TODO: really works on 1.8.7?
- klass = self.kind_of? Module
- target = klass ? "#{self}." : "#{self.class}#"
- msg = [ "NOTE: #{target}#{name} is deprecated",
- repl == :none ? " with no replacement" : ", use #{repl}",
- ". It will be removed on or after %4d-%02d-01." % [year, month],
- "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
- ]
- warn "#{msg.join}." unless Deprecate.skip
+ unless Deprecate.skip
+ klass =
+ warning = Warning.new({
+ :target => (self.kind_of? Module) ? "#{self}." : "#{self.class}#",
+ :method_name => name,
+ :location => Gem.location_of_caller,
+ :replacement => repl,
+ :year => year,
+ :month => month
+ })
+ Deprecate.add_warning warning
+ end
send old, *args, &block
end
}
View
5 lib/rubygems/specification.rb
@@ -274,6 +274,9 @@ def self._all # :nodoc:
def self._resort! # :nodoc:
@@all.sort! { |a, b|
+ if a.nil? or b.nil?
+ p self
+ end
names = a.name <=> b.name
next names if names.nonzero?
b.version <=> a.version
@@ -547,7 +550,7 @@ def self.load file
rescue SignalException, SystemExit
raise
rescue SyntaxError, Exception => e
- warn "Invalid gemspec in [#{file}]: #{e}"
+ warn "Invalid gemspec in [#{file}]: #{e}\n\t#{e.backtrace.first}"
end
nil
View
171 test/rubygems/test_deprecate.rb
@@ -6,29 +6,33 @@
class TestDeprecate < Gem::TestCase
- def test_defaults
- assert_equal true, Deprecate.skip
+ def setup
+ Deprecate.saved_warnings.clear
+ @original_skip = Deprecate.skip
+ Deprecate.skip = false
end
+ def teardown
+ Deprecate.saved_warnings.clear
+ Deprecate.skip = @original_skip
+ end
+
+ def test_defaults
+ assert_equal Deprecate::SKIP_DEFAULT, @original_skip
+ end
+
def test_assignment
Deprecate.skip = false
-
assert_equal false, Deprecate.skip
-
- Deprecate.skip = nil
+ Deprecate.skip = true
assert_equal true, Deprecate.skip
- Deprecate.skip = false
-
- assert_equal false, Deprecate.skip
-
Deprecate.skip = nil
+ assert([true,false].include? Deprecate.skip)
end
-
+
def test_skip
- Deprecate.skip = false
-
Deprecate.skip_during do
assert_equal true, Deprecate.skip
end
@@ -36,11 +40,150 @@ def test_skip
Deprecate.skip_during(false) do
assert_equal false, Deprecate.skip
end
-
+
Deprecate.skip_during(nil) do
- assert_equal true, Deprecate.skip
+ assert_equal Deprecate::SKIP_DEFAULT, Deprecate.skip
end
Deprecate.skip = nil
end
+
+ ### stolen from Wrong::Helpers
+
+ # Usage:
+ # capturing { puts "hi" } => "hi\n"
+ # capturing(:stderr) { $stderr.puts "hi" } => "hi\n"
+ # out, err = capturing(:stdout, :stderr) { ... }
+ #
+ # see http://www.justskins.com/forums/closing-stderr-105096.html for more explanation
+ def capturing(*streams)
+ streams = [:stdout] if streams.empty?
+ original = {}
+ captured = {}
+
+ # reassign the $ variable (which is used by well-behaved code e.g. puts)
+ streams.each do |stream|
+ original[stream] = (stream == :stdout ? $stdout : $stderr)
+ captured[stream] = StringIO.new
+ reassign_stream(stream, captured)
+ end
+
+ yield
+
+ # return either one string, or an array of two strings
+ if streams.size == 1
+ captured[streams.first].string
+ else
+ [captured[streams[0]].string.to_s, captured[streams[1]].string.to_s]
+ end
+
+ ensure
+
+ streams.each do |stream|
+ # bail if stream was reassigned inside the block
+ if (stream == :stdout ? $stdout : $stderr) != captured[stream]
+ raise "#{stream} was reassigned while being captured"
+ end
+ # support nested calls to capturing
+ original[stream] << captured[stream].string if original[stream].is_a? StringIO
+ reassign_stream(stream, original)
+ end
+ end
+
+ private
+ def reassign_stream(which, streams)
+ case which
+ when :stdout
+ $stdout = streams[which]
+ when :stderr
+ $stderr = streams[which]
+ end
+ end
+ ### end of Wrong::Helpers code
+
+ public
+ def test_has_a_place_to_save_warnings
+ assert_empty Deprecate.saved_warnings
+ end
+
+ class Thing
+ extend Deprecate
+ attr_accessor :message
+ def foo
+ @message = "foo"
+ end
+ def bar
+ @message = "bar"
+ end
+ def goo
+ @message = "goo"
+ end
+ deprecate :foo, :bar, 2099, 3
+ deprecate :goo, :bar, 2099, 4
+ end
+
+ def test_deprecated_method_calls_the_old_method
+ capturing :stderr do
+ thing = Thing.new
+ thing.foo
+ assert_equal "foo", thing.message
+ end
+ end
+
+ def test_deprecated_method_outputs_a_warning
+ out, err = capturing(:stdout, :stderr) do
+ thing = Thing.new
+ thing.foo
+ end
+ assert_equal "", out
+ assert err =~ /Thing#foo is deprecated; use bar instead/, err
+ assert err =~ /on or after 2099-03-01/, err
+ end
+
+ def test_saves_warnings
+ capturing :stderr do
+ thing = Thing.new
+ thing.foo
+ thing.goo
+ assert_equal 2, Deprecate.saved_warnings.size
+ end
+ end
+
+ def test_suppresses_duplicate_warnings
+ capturing :stderr do
+ line1 = line2 = nil
+ thing = Thing.new
+ 3.times do
+ thing.foo; line1 = __LINE__
+ end
+ thing.foo; line2 = __LINE__
+ assert_equal 2, Deprecate.saved_warnings.size
+ assert_equal line1, Deprecate.saved_warnings[0].location.last
+ assert_equal line2, Deprecate.saved_warnings[1].location.last
+ end
+ end
+
+ def test_suppresses_further_warnings_until_exit
+ Deprecate.saved_warnings.clear
+ end
+
+ def test_report
+ err = capturing :stderr do
+ thing = Thing.new
+ thing.foo
+ thing.foo
+ thing.goo
+ thing.foo
+ s = Deprecate.report
+ assert_equal s, <<-REPORT
+Some of your installed gems called deprecated methods. See http://blog.zenspider.com/2011/05/rubygems-18-is-coming.html for background. Use 'gem pristine --all' to fix or 'rubygems update --system 1.7.2' to downgrade.
+TestDeprecate::Thing#foo is deprecated; use bar instead. It will be removed on or after 2099-03-01.
+ called from /Users/chaffee/dev/rubygems/test/rubygems/test_deprecate.rb:173
+ called from /Users/chaffee/dev/rubygems/test/rubygems/test_deprecate.rb:174
+ called from /Users/chaffee/dev/rubygems/test/rubygems/test_deprecate.rb:176
+TestDeprecate::Thing#goo is deprecated; use bar instead. It will be removed on or after 2099-04-01.
+ called from /Users/chaffee/dev/rubygems/test/rubygems/test_deprecate.rb:175
+ REPORT
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.