From 473bc9f2d6a0ebd93c9a09ea3c699c14e01330b0 Mon Sep 17 00:00:00 2001 From: Kyrylo Silin Date: Sat, 4 May 2019 17:15:14 +0300 Subject: Add Pry::Warning Quite often, when we deprecate APIs, we want to print a warning. Such a warning would be hard to track without a file and line location. We are trying to be a good citizen and print warnings like Ruby does it. --- lib/pry.rb | 1 + lib/pry/command.rb | 6 +----- lib/pry/prompt.rb | 16 +++++++--------- lib/pry/warning.rb | 25 +++++++++++++++++++++++++ spec/warning_spec.rb | 10 ++++++++++ 5 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 lib/pry/warning.rb create mode 100644 spec/warning_spec.rb diff --git a/lib/pry.rb b/lib/pry.rb index 623562c1..276a41e9 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -25,6 +25,7 @@ require 'pry/exception_handler' require 'pry/system_command_handler' require 'pry/control_d_handler' require 'pry/command_state' +require 'pry/warning' Pry::Commands = Pry::CommandSet.new unless defined?(Pry::Commands) diff --git a/lib/pry/command.rb b/lib/pry/command.rb index fa6d2e51..4e1674c7 100644 --- a/lib/pry/command.rb +++ b/lib/pry/command.rb @@ -288,11 +288,7 @@ class Pry end def _pry_ - loc = caller_locations(1..1).first - warn( - "#{loc.path}:#{loc.lineno}: warning: _pry_ is deprecated, use " \ - "pry_instance instead" - ) + Pry::Warning.warn('_pry_ is deprecated, use pry_instance instead') pry_instance end diff --git a/lib/pry/prompt.rb b/lib/pry/prompt.rb index 906a5f01..1e47174f 100644 --- a/lib/pry/prompt.rb +++ b/lib/pry/prompt.rb @@ -132,19 +132,17 @@ class Pry # @deprecated Use a `Pry::Prompt` instance directly def [](key) key = key.to_s - loc = caller_locations(1..1).first - if %w[name description].include?(key) - warn( - "#{loc.path}:#{loc.lineno}: warning: `Pry::Prompt[:#{@name}][:#{key}]` " \ - "is deprecated. Use `#{self.class}##{key}` instead" + Pry::Warning.warn( + "`Pry::Prompt[:#{@name}][:#{key}]` is deprecated. " \ + "Use `#{self.class}##{key}` instead" ) public_send(key) elsif key.to_s == 'value' - warn( - "#{loc.path}:#{loc.lineno}: warning: `#{self.class}[:#{@name}][:value]` " \ - "is deprecated. Use `#{self.class}#prompt_procs` instead or an " \ - "instance of `#{self.class}` directly" + Pry::Warning.warn( + "`#{self.class}[:#{@name}][:value]` is deprecated. Use " \ + "`#{self.class}#prompt_procs` instead or an instance of " \ + "`#{self.class}` directly" ) @prompt_procs end diff --git a/lib/pry/warning.rb b/lib/pry/warning.rb new file mode 100644 index 00000000..6f7bee76 --- /dev/null +++ b/lib/pry/warning.rb @@ -0,0 +1,25 @@ +class Pry + # @api private + # @since ?.?.? + module Warning + # Prints a warning message with exact file and line location, similar to how + # Ruby's -W prints warnings. + # + # @param [String] message + # @return [void] + def self.warn(message) + if Kernel.respond_to?(:caller_locations) + location = caller_locations(1..1).first + path = location.path + lineno = location.lineno + else + # Ruby 1.9.3 support. + frame = caller.first.split(':') # rubocop:disable Performance/Caller + path = frame.first + lineno = frame[1] + end + + Kernel.warn("#{path}:#{lineno}: warning: #{message}") + end + end +end diff --git a/spec/warning_spec.rb b/spec/warning_spec.rb new file mode 100644 index 00000000..3f7328ce --- /dev/null +++ b/spec/warning_spec.rb @@ -0,0 +1,10 @@ +RSpec.describe Pry::Warning do + describe "#warn" do + it "prints a warning with file and line" do + expect(Kernel).to receive(:warn).with( + "#{__FILE__}:#{__LINE__ + 2}: warning: foo bar" + ) + described_class.warn('foo bar') + end + end +end -- cgit v1.2.1