From b50195fde727914ef90c47de7157f7703fc2f49e Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Mon, 7 Mar 2016 01:03:04 -0600 Subject: [PATCH] Add a deprecation DSL --- lib/active_model/serializer/adapter.rb | 19 +++---- .../serializer/adapter/attributes.rb | 7 +-- lib/active_model/serializer/adapter/base.rb | 6 +-- lib/active_model/serializer/adapter/json.rb | 7 +-- .../serializer/adapter/json_api.rb | 7 +-- lib/active_model/serializer/adapter/null.rb | 7 +-- .../serializer/array_serializer.rb | 6 +-- lib/active_model_serializers.rb | 10 ++++ lib/active_model_serializers/deprecate.rb | 49 +++++++++++++++++++ test/array_serializer_test.rb | 4 +- 10 files changed, 91 insertions(+), 31 deletions(-) create mode 100644 lib/active_model_serializers/deprecate.rb diff --git a/lib/active_model/serializer/adapter.rb b/lib/active_model/serializer/adapter.rb index f49d3612..3a6a3ee2 100644 --- a/lib/active_model/serializer/adapter.rb +++ b/lib/active_model/serializer/adapter.rb @@ -3,40 +3,37 @@ module ActiveModel # @deprecated Use ActiveModelSerializers::Adapter instead module Adapter class << self + extend ActiveModelSerializers::Deprecate + def create(resource, options = {}) - warn_deprecation ActiveModelSerializers::Adapter.create(resource, options) end + deprecate :create, 'ActiveModelSerializers::Adapter.' def adapter_class(adapter) - warn_deprecation ActiveModelSerializers::Adapter.adapter_class(adapter) end + deprecate :adapter_class, 'ActiveModelSerializers::Adapter.' def adapter_map - warn_deprecation ActiveModelSerializers::Adapter.adapter_map end + deprecate :adapter_map, 'ActiveModelSerializers::Adapter.' def adapters - warn_deprecation ActiveModelSerializers::Adapter.adapters end + deprecate :adapters, 'ActiveModelSerializers::Adapter.' def register(name, klass = name) - warn_deprecation ActiveModelSerializers::Adapter.register(name, klass) end + deprecate :register, 'ActiveModelSerializers::Adapter.' def lookup(adapter) - warn_deprecation ActiveModelSerializers::Adapter.lookup(adapter) end - - def warn_deprecation - warn "Calling deprecated #{name} (#{__FILE__}) from #{caller[1..3].join(', ')}. Please use ActiveModelSerializers::Adapter" - end - private :warn_deprecation + deprecate :lookup, 'ActiveModelSerializers::Adapter.' end require 'active_model/serializer/adapter/base' diff --git a/lib/active_model/serializer/adapter/attributes.rb b/lib/active_model/serializer/adapter/attributes.rb index 30b70fa2..e04e5fd8 100644 --- a/lib/active_model/serializer/adapter/attributes.rb +++ b/lib/active_model/serializer/adapter/attributes.rb @@ -1,13 +1,14 @@ -require 'active_model_serializers/adapter/attributes' - module ActiveModel class Serializer module Adapter class Attributes < DelegateClass(ActiveModelSerializers::Adapter::Attributes) def initialize(serializer, options = {}) - warn "Calling deprecated #{self.class.name} (#{__FILE__}) from #{caller[0..2].join(', ')}. Please use #{self.class.name.sub('ActiveModel::Serializer', 'ActiveModelSerializers')}" super(ActiveModelSerializers::Adapter::Attributes.new(serializer, options)) end + class << self + extend ActiveModelSerializers::Deprecate + deprecate :new, 'ActiveModelSerializers::Adapter::Json.' + end end end end diff --git a/lib/active_model/serializer/adapter/base.rb b/lib/active_model/serializer/adapter/base.rb index bc6330a8..f27328f7 100644 --- a/lib/active_model/serializer/adapter/base.rb +++ b/lib/active_model/serializer/adapter/base.rb @@ -2,9 +2,9 @@ module ActiveModel class Serializer module Adapter class Base < DelegateClass(ActiveModelSerializers::Adapter::Base) - def self.inherited(base) - warn "Inheriting deprecated ActiveModel::Serializer::Adapter::Base in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter::Base" - super + class << self + extend ActiveModelSerializers::Deprecate + deprecate :inherited, 'ActiveModelSerializers::Adapter::Base.' end def initialize(serializer, options = {}) diff --git a/lib/active_model/serializer/adapter/json.rb b/lib/active_model/serializer/adapter/json.rb index 0b145db0..1998a4c6 100644 --- a/lib/active_model/serializer/adapter/json.rb +++ b/lib/active_model/serializer/adapter/json.rb @@ -1,13 +1,14 @@ -require 'active_model_serializers/adapter/json' - module ActiveModel class Serializer module Adapter class Json < DelegateClass(ActiveModelSerializers::Adapter::Json) def initialize(serializer, options = {}) - warn "Calling deprecated #{self.class.name} (#{__FILE__}) from #{caller[0..2].join(', ')}. Please use #{self.class.name.sub('ActiveModel::Serializer', 'ActiveModelSerializers')}" super(ActiveModelSerializers::Adapter::Json.new(serializer, options)) end + class << self + extend ActiveModelSerializers::Deprecate + deprecate :new, 'ActiveModelSerializers::Adapter::Json.new' + end end end end diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index 0386f760..13777cdc 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -1,13 +1,14 @@ -require 'active_model_serializers/adapter/json_api' - module ActiveModel class Serializer module Adapter class JsonApi < DelegateClass(ActiveModelSerializers::Adapter::JsonApi) def initialize(serializer, options = {}) - warn "Calling deprecated #{self.class.name} (#{__FILE__}) from #{caller[0..2].join(', ')}. Please use #{self.class.name.sub('ActiveModel::Serializer', 'ActiveModelSerializers')}" super(ActiveModelSerializers::Adapter::JsonApi.new(serializer, options)) end + class << self + extend ActiveModelSerializers::Deprecate + deprecate :new, 'ActiveModelSerializers::Adapter::JsonApi.new' + end end end end diff --git a/lib/active_model/serializer/adapter/null.rb b/lib/active_model/serializer/adapter/null.rb index 5f5b4bce..906953d1 100644 --- a/lib/active_model/serializer/adapter/null.rb +++ b/lib/active_model/serializer/adapter/null.rb @@ -1,13 +1,14 @@ -require 'active_model_serializers/adapter/null' - module ActiveModel class Serializer module Adapter class Null < DelegateClass(ActiveModelSerializers::Adapter::Null) def initialize(serializer, options = {}) - warn "Calling deprecated #{self.class.name} (#{__FILE__}) from #{caller[0..2].join(', ')}. Please use #{self.class.name.sub('ActiveModel::Serializer', 'ActiveModelSerializers')}" super(ActiveModelSerializers::Adapter::Null.new(serializer, options)) end + class << self + extend ActiveModelSerializers::Deprecate + deprecate :new, 'ActiveModelSerializers::Adapter::Null.new' + end end end end diff --git a/lib/active_model/serializer/array_serializer.rb b/lib/active_model/serializer/array_serializer.rb index 97efa864..b36fd971 100644 --- a/lib/active_model/serializer/array_serializer.rb +++ b/lib/active_model/serializer/array_serializer.rb @@ -1,9 +1,9 @@ require 'active_model/serializer/collection_serializer' class ActiveModel::Serializer class ArraySerializer < CollectionSerializer - def initialize(*) - warn "Calling deprecated ArraySerializer in #{caller[0..2].join(', ')}. Please use CollectionSerializer" - super + class << self + extend ActiveModelSerializers::Deprecate + deprecate :new, 'ActiveModel::CollectionSerializer.' end end end diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb index bf2dac13..7e036c6b 100644 --- a/lib/active_model_serializers.rb +++ b/lib/active_model_serializers.rb @@ -11,6 +11,7 @@ module ActiveModelSerializers autoload :Test autoload :Adapter autoload :JsonPointer + autoload :Deprecate class << self; attr_accessor :logger; end self.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) @@ -19,6 +20,15 @@ module ActiveModelSerializers ActiveModel::Serializer.config end + # The file name and line number of the caller of the caller of this method. + def self.location_of_caller + caller[1] =~ /(.*?):(\d+).*?$/i + file = Regexp.last_match(1) + lineno = Regexp.last_match(2).to_i + + [file, lineno] + end + require 'active_model/serializer/version' require 'active_model/serializer' require 'active_model/serializable_resource' diff --git a/lib/active_model_serializers/deprecate.rb b/lib/active_model_serializers/deprecate.rb new file mode 100644 index 00000000..ba95c07f --- /dev/null +++ b/lib/active_model_serializers/deprecate.rb @@ -0,0 +1,49 @@ +## +# Provides a single method +deprecate+ to be used to declare when +# something is going away. +# +# class Legacy +# def self.klass_method +# # ... +# end +# +# def instance_method +# # ... +# end +# +# extend ActiveModelSerializers::Deprecate +# deprecate :instance_method, "ActiveModelSerializers::NewPlace#new_method" +# +# class << self +# extend ActiveModelSerializers::Deprecate +# deprecate :klass_method, :none +# end +# end +# +# Adapted from https://github.com/rubygems/rubygems/blob/1591331/lib/rubygems/deprecate.rb +module ActiveModelSerializers + module Deprecate + ## + # Simple deprecation method that deprecates +name+ by wrapping it up + # in a dummy method. It warns on each call to the dummy method + # telling the user of +replacement+ (unless +replacement+ is :none) that it is planned to go away. + + def deprecate(name, replacement) + old = "_deprecated_#{name}" + alias_method old, name + class_eval do + define_method(name) do |*args, &block| + target = self.is_a?(Module) ? "#{self}." : "#{self.class}#" + msg = ["NOTE: #{target}#{name} is deprecated", + replacement == :none ? ' with no replacement' : "; use #{replacement} instead", + "\n#{target}#{name} called from #{ActiveModelSerializers.location_of_caller.join(":")}" + ] + warn "#{msg.join}." + send old, *args, &block + end + end + end + + module_function :deprecate + end +end diff --git a/test/array_serializer_test.rb b/test/array_serializer_test.rb index 50028371..bafef464 100644 --- a/test/array_serializer_test.rb +++ b/test/array_serializer_test.rb @@ -11,7 +11,7 @@ module ActiveModel _, stderr = capture_io do super end - if stderr !~ /Calling deprecated ArraySerializer/ + if stderr !~ /NOTE: ActiveModel::Serializer::ArraySerializer.new is deprecated/ fail Minitest::Assertion, stderr end end @@ -29,7 +29,7 @@ module ActiveModel serializer = ArraySerializer.new([comment, post]) assert_equal 'comments', serializer.json_key end - assert_match(/Calling deprecated ArraySerializer/, stderr) + assert_match(/NOTE: ActiveModel::Serializer::ArraySerializer.new is deprecated/, stderr) end end end