Skip to content

Commit

Permalink
Merge branch 'v2.0.0'
Browse files Browse the repository at this point in the history
closes #3
  • Loading branch information
Mike Blumtritt committed Feb 17, 2015
1 parent 62f31f1 commit 8ffb2b6
Show file tree
Hide file tree
Showing 14 changed files with 384 additions and 436 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### deprecations 2.0.0
- supports custom behavior
- supports temporary behavior change
- supports inheritance of deprecated methods
- `Deprecations#configure` and `Deprecations#configuration` are obsolete (use `Deprecations#behavior`)

### deprecations 1.0.6
- support for textual alternative of deprecated methods

Expand Down
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Deprecations

This gem provides transparent declaration of deprecated methods and classes.
This gem provides transparent declaration of deprecated methods and classes. It's easy, small, has no dependencies and no overhead.

[![Code Climate](https://codeclimate.com/github/mblumtritt/deprecations.png)](https://codeclimate.com/github/mblumtritt/deprecations)

Expand Down Expand Up @@ -46,6 +46,7 @@ class MySample
def clean
clear
end

deprecated :clean, :clear, 'next version'

end
Expand All @@ -55,27 +56,43 @@ Whenever the method `MySample#clean` is called this warning appears:

> [DEPRECATION] `MySample#clean` is deprecated and will be outdated next version. Please use `MySample#clear` instead.
You can change this behavior by configure the Deprecations gem:
Marking a complete class as deprecated will present the deprecation warning whenever this class is instantiated:

```ruby
Deprecations.configure do |config|
config.behavior = :raise
class MySample
deprecated!

# some more code here...
end
```

Valid behaviors are:
You can change the behavior of notifying:

```ruby
Deprecations.behavior = :raise
```

There are 3 pre-defined behaviors:

- `:raise` will raise an `DeprecationException` when a deprecated method is called
- `:silence` will do nothing
- `:silence` will do nothing (ignore the deprecation)
- `:warn` will print a warning (default behavior)

Marking a complete class as deprecated will present the deprecation warning (or exception) whenever this class is instantiated:
Besides this you can implement your own:

```ruby
class MySample
deprecated!

# some more code here...
Deprecations.behavior = proc do |subject, _alternative, _outdated|
SuperLogger.warning "deprecated: #{subject}"
end
```

Any object responding to `#call` will be accepted as a valid handler.

Whenever you need to temporary change the standard behavior (like e.g. in your specs) you can do this like

```ruby
Deprecations.set_behavior(:silent) do
MyDeprecatedClass.new.do_some_magic
end
```

Expand Down
3 changes: 1 addition & 2 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
ENV.key?('NO_RUBYGEMS') or require('rubygems')
require 'bundler/gem_tasks'

require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:test) do |t|
t.pattern = ['spec/*_spec.rb', 'spec/**/*/*_spec.rb']
t.rspec_opts = '-w'
Expand Down
10 changes: 6 additions & 4 deletions deprecations.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require File.expand_path('../lib/deprecations/version', __FILE__)

GemSpec= Gem::Specification.new do |spec|
GemSpec = Gem::Specification.new do |spec|
spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
spec.platform = Gem::Platform::RUBY
spec.required_ruby_version = '>= 2.0.0'
Expand All @@ -9,20 +9,22 @@ GemSpec= Gem::Specification.new do |spec|
spec.authors = ['Mike Blumtritt']
spec.email = %w[mike.blumtritt@injixo.com]
spec.summary = 'Deprecation support for your project.'
spec.description = 'This gem provides transparent declaration of deprecated methods and classes.'
spec.description = "This gem provides transparent declaration of deprecated methods and classes. "\
"It's easy, small, has no dependencies and no overhead."
spec.homepage = 'https://github.com/mblumtritt/deprecations'
spec.date = Time.now.strftime('%Y-%m-%d')
spec.require_paths = %w[lib]
spec.files = %x[git ls-files].split($/)
spec.test_files = spec.files.grep(%r[^test/])
spec.extra_rdoc_files = %w[README.md]
spec.test_files = spec.files.grep(%r[^spec/])
spec.extra_rdoc_files = %w[README.md CHANGELOG.md]
spec.has_rdoc = false # TODO!
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec', '>= 3.0.0'
spec.add_development_dependency 'guard'
spec.add_development_dependency 'guard-rspec'
if /darwin|mac os/i =~ RUBY_PLATFORM
spec.add_development_dependency 'rb-fsevent'
spec.add_development_dependency 'terminal-notifier'
spec.add_development_dependency 'terminal-notifier-guard'
end
end
42 changes: 8 additions & 34 deletions lib/deprecations.rb
Original file line number Diff line number Diff line change
@@ -1,40 +1,14 @@

DeprecationError = Class.new(ScriptError)

module Deprecations
autoload(:VERSION, "#{__FILE__[/.*(?=\..+$)/]}/version")
require_relative 'deprecations/configuration'
require_relative 'deprecations/extension'
require_relative 'deprecations/behavior'

class << self

def call(subject, alternative, outdated)
case configuration.behavior
when :warn
warn(subject, alternative, outdated)
when :raise
throw!(subject, alternative)
end
self
end

private

def throw!(subject, alternative)
msg = "`#{subject}` is deprecated"
alternative and msg << " - use #{alternative} instead"
ex = DeprecationError.new(msg)
ex.set_backtrace(caller(3))
raise(ex)
end

def warn(subject, alternative, outdated)
location = ::Kernel.caller_locations(3,1).last and location = "#{location.path}:#{location.lineno}: "
msg = "#{location}[DEPRECATION] `#{subject}` is deprecated"
msg << (outdated ? " and will be outdated #{outdated}." : '.')
alternative and msg << " Please use `#{alternative}` instead."
::Kernel.warn(msg)
end

def self.call(subject, alternative, outdated)
@behavior.call(subject, alternative, outdated)
self
end

self.behavior = :warn
end

DeprecationError = Class.new(ScriptError)
55 changes: 55 additions & 0 deletions lib/deprecations/behavior.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Deprecations
class << self

def behavior
BEHAVIOR.key(@behavior) || @behavior
end

def behavior=(behavior)
@behavior = as_behavior(behavior)
end

def set_behavior(behavior)
behavior = as_behavior(behavior)
block_given? or raise(ArgumentError, 'block expected')
current_behavior = @behavior
begin
@behavior = behavior
yield
ensure
@behavior = current_behavior
end
end

private

def as_behavior(arg)
defined?(arg.call) ? arg : BEHAVIOR.fetch(arg) do
raise(ArgumentError, "invalid parameter - behavior has to be #{valid_behavior} or need to respond to `call`")
end
end

def valid_behavior
BEHAVIOR.keys.map(&:inspect).join(' | ')
end

BEHAVIOR = {
silence: ->(*){},
raise: proc do |subject, alternative|
msg = "`#{subject}` is deprecated"
alternative and msg << " - use #{alternative} instead"
ex = ::DeprecationError.new(msg)
ex.set_backtrace(caller(4))
raise(ex)
end,
warn: proc do |subject, alternative, outdated |
location = caller_locations(4, 1).last and location = "#{location.path}:#{location.lineno}: "
msg = "#{location}[DEPRECATION] `#{subject}` is deprecated"
msg << (outdated ? " and will be outdated #{outdated}." : '.')
alternative and msg << " Please use `#{alternative}` instead."
::Kernel.warn(msg)
end
}

end
end
35 changes: 0 additions & 35 deletions lib/deprecations/configuration.rb

This file was deleted.

19 changes: 12 additions & 7 deletions lib/deprecations/extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ def __method(method_name)
end

def __method_deprecated!(method, alternative, outdated)
defining_context = self
define_method(method.name) do |*a, &b|
decorated = Class === self ? "#{self}." : "#{self.class}#"
decorated = Class === self ? "#{self}." : "#{defining_context}#"
Deprecations.call(
"#{decorated}#{__method__}",
"#{decorated}#{::Kernel.__method__}",
UnboundMethod === alternative ? "#{decorated}#{alternative.name}" : alternative,
outdated
)
Expand All @@ -29,16 +30,21 @@ def __method_not_found!(method_name)
raise(NameError, "undefined method `#{method_name}` for class `#{self}`")
end

def __method_alternative(alternative)
Symbol === alternative ? (__method(alternative) or __method_not_found!(alternative)) : alternative
end
end

module ClassMethods
private
include Helper

def deprecated(method_name, alternative = nil, outdated = nil)
m = __method(method_name) or __method_not_found!(method_name)
a = Symbol === alternative ? (__method(alternative) or __method_not_found!(alternative)) : alternative
__method_deprecated!(m, a, outdated)
__method_deprecated!(
(__method(method_name) or __method_not_found!(method_name)),
__method_alternative(alternative),
outdated
)
end
end

Expand All @@ -48,8 +54,7 @@ module InstanceMethods

def deprecated(method_name, alternative = nil, outdated = nil)
m = __method(method_name) or return singleton_class.send(:deprecated, method_name, alternative, outdated)
a = Symbol === alternative ? (__method(alternative) or __method_not_found!(alternative)) : alternative
__method_deprecated!(m, a, outdated)
__method_deprecated!(m, __method_alternative(alternative), outdated)
end

def deprecated!(alternative = nil, outdated = nil)
Expand Down
2 changes: 1 addition & 1 deletion lib/deprecations/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Deprecations
VERSION = '1.0.6'
VERSION = '2.0.0pre'
end
Loading

0 comments on commit 8ffb2b6

Please sign in to comment.