deprecator 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +72 -0
- data/Rakefile +4 -0
- data/examples/example.rb +31 -0
- data/examples/example2.rb +33 -0
- data/lib/deprecator.rb +33 -11
- data/lib/deprecator/core_ext.rb +1 -1
- data/lib/deprecator/strategy.rb +79 -12
- data/lib/deprecator/version.rb +1 -1
- data/spec/deprecator_spec.rb +29 -1
- metadata +4 -2
data/README.md
CHANGED
@@ -2,11 +2,17 @@
|
|
2
2
|
|
3
3
|
Yet another library for dealing with code deprecation in ruby gracefully.
|
4
4
|
|
5
|
+
Allows you to replace behavior. For example before some important release you want to revise all deprecated code that is being called by your tests (and you have near 100% coverage, don't you?) - you can just throw in a strategy, that raises an error.
|
6
|
+
|
7
|
+
The same technique also provides for ability to make deprecation messages localized via l10n/i18n etc.
|
8
|
+
|
5
9
|
## Installation
|
6
10
|
|
7
11
|
Add this line to your application's Gemfile:
|
8
12
|
|
13
|
+
```ruby
|
9
14
|
gem 'deprecator'
|
15
|
+
```
|
10
16
|
|
11
17
|
And then execute:
|
12
18
|
|
@@ -20,7 +26,73 @@ Or install it yourself as:
|
|
20
26
|
|
21
27
|
```ruby
|
22
28
|
|
29
|
+
#!/usr/bin/env ruby
|
30
|
+
|
31
|
+
require 'deprecator'
|
32
|
+
|
33
|
+
class SomeClass
|
34
|
+
deprecated
|
35
|
+
|
36
|
+
def method1
|
37
|
+
deprecated
|
38
|
+
end
|
39
|
+
|
40
|
+
def method2
|
41
|
+
if true
|
42
|
+
deprecated "this is deprecated when true is true"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
deprecated_method
|
47
|
+
def method3
|
48
|
+
end
|
49
|
+
|
50
|
+
deprecated_method :method4, "%{method} is no longer here, use some other method!"
|
51
|
+
deprecated_method [:method5, :method6], "%{method} is no longer here, use some other method!"
|
52
|
+
end
|
53
|
+
|
54
|
+
obj = SomeClass.new # outputs to stderr: [DEPRECATED] deprecated class SomeClass instantiated at /Users/vasfed/work/deprecator/examples/example.rb:26:in `new'
|
55
|
+
obj.method1 # [DEPRECATED] method1 is deprecated!
|
56
|
+
obj.method2 # [DEPRECATED] this is deprecated when true is true
|
57
|
+
obj.method3 # [DEPRECATED] method method3 is deprecated. Called from /Users/vasfed/work/deprecator/examples/example.rb:28:in `<top (required)>'
|
58
|
+
obj.method4 # [DEPRECATED] method4 is no longer here, use some other method!
|
59
|
+
obj.method6 # [DEPRECATED] method6 is no longer here, use some other method!
|
60
|
+
|
61
|
+
```
|
62
|
+
|
63
|
+
changing strategies:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
|
67
|
+
Deprecator.strategy = :raise # included: warning(default), raise, raiseHard
|
68
|
+
|
69
|
+
class SomeClass
|
70
|
+
deprecated "some reason"
|
71
|
+
def initialize
|
72
|
+
puts "SomeClass#initialize called"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
begin
|
77
|
+
SomeClass.new
|
78
|
+
rescue Deprecator::Deprecated => e
|
79
|
+
puts "caught exception #{e.class}: #{e}"
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
class CustomStrategy < Deprecator::Strategy::Base
|
84
|
+
def object_found *args
|
85
|
+
puts "Deprecated object created."
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Deprecator.strategy = CustomStrategy
|
90
|
+
SomeClass.new
|
23
91
|
|
92
|
+
# outputs:
|
93
|
+
# caught exception Deprecator::DeprecatedObjectCreated: some reason
|
94
|
+
# Deprecated object created.
|
95
|
+
# SomeClass#initialize called
|
24
96
|
|
25
97
|
```
|
26
98
|
|
data/Rakefile
CHANGED
data/examples/example.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'deprecator'
|
4
|
+
|
5
|
+
class SomeClass
|
6
|
+
deprecated
|
7
|
+
|
8
|
+
def method1
|
9
|
+
deprecated
|
10
|
+
end
|
11
|
+
|
12
|
+
def method2
|
13
|
+
if true
|
14
|
+
deprecated "this is deprecated when true is true"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
deprecated_method
|
19
|
+
def method3
|
20
|
+
end
|
21
|
+
|
22
|
+
deprecated_method :method4, "%{method} is no longer here, use some other method!"
|
23
|
+
deprecated_method [:method5, :method6], "%{method} is no longer here, use some other method!"
|
24
|
+
end
|
25
|
+
|
26
|
+
obj = SomeClass.new # outputs to stderr: [DEPRECATED] deprecated class SomeClass instantiated at /Users/vasfed/work/deprecator/examples/example.rb:26:in `new'
|
27
|
+
obj.method1 # [DEPRECATED] method1 is deprecated!
|
28
|
+
obj.method2 # [DEPRECATED] this is deprecated when true is true
|
29
|
+
obj.method3 # [DEPRECATED] method method3 is deprecated. Called from /Users/vasfed/work/deprecator/examples/example.rb:28:in `<top (required)>'
|
30
|
+
obj.method4 # [DEPRECATED] method4 is no longer here, use some other method!
|
31
|
+
obj.method6 # [DEPRECATED] method6 is no longer here, use some other method!
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'deprecator'
|
4
|
+
|
5
|
+
Deprecator.strategy = :raise # included: warning(default), raise, raiseHard
|
6
|
+
|
7
|
+
class SomeClass
|
8
|
+
deprecated "some reason"
|
9
|
+
def initialize
|
10
|
+
puts "SomeClass#initialize called"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
SomeClass.new
|
16
|
+
rescue Deprecator::Deprecated => e
|
17
|
+
puts "caught exception #{e.class}: #{e}"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class CustomStrategy < Deprecator::Strategy::Base
|
22
|
+
def object_found *args
|
23
|
+
puts "Deprecated object created."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Deprecator.strategy = CustomStrategy
|
28
|
+
SomeClass.new
|
29
|
+
|
30
|
+
# outputs:
|
31
|
+
# caught exception Deprecator::DeprecatedObjectCreated: some reason
|
32
|
+
# Deprecated object created.
|
33
|
+
# SomeClass#initialize called
|
data/lib/deprecator.rb
CHANGED
@@ -4,28 +4,48 @@ require 'is_a'
|
|
4
4
|
|
5
5
|
module Deprecator
|
6
6
|
|
7
|
+
class UnknownStrategy < ArgumentError; end
|
8
|
+
|
9
|
+
class Deprecated < RuntimeError; end
|
10
|
+
class DeprecatedMethodCalled < Deprecated; end
|
11
|
+
class DeprecatedObjectCreated < Deprecated; end
|
12
|
+
|
13
|
+
class CodeError < RuntimeError; end
|
14
|
+
class NotImplemented < CodeError; end
|
15
|
+
class Fixme < CodeError; end
|
16
|
+
class Todo < CodeError; end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
7
21
|
class DeprecatedClass
|
8
22
|
def self.inherited cls
|
9
|
-
|
23
|
+
::Deprecator.strategy.class_found(cls, caller_line)
|
24
|
+
# cls.extend(Deprecated::ClassMethods)
|
25
|
+
# cls.send :include, Deprecated::InstanceMethods
|
10
26
|
end
|
11
27
|
end
|
12
28
|
|
13
|
-
module
|
29
|
+
module DeprecatorModule
|
14
30
|
def self.included cls
|
15
31
|
cls.extend self
|
16
32
|
end
|
17
33
|
|
18
34
|
def self.extended cls
|
19
35
|
::Deprecator.strategy.class_found(cls, caller_line)
|
20
|
-
cls.send :include, InstanceMethods
|
36
|
+
# cls.send :include, InstanceMethods
|
37
|
+
# cls.extend ClassMethods
|
21
38
|
end
|
22
39
|
|
23
|
-
module
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
40
|
+
# module ClassMethods
|
41
|
+
# end
|
42
|
+
|
43
|
+
# module InstanceMethods
|
44
|
+
# # SMELL: initialize in module is no good, but in this case may help for some cases
|
45
|
+
# def initialize *args
|
46
|
+
# ::Deprecator.strategy.object_found(self, caller_line)
|
47
|
+
# end
|
48
|
+
# end
|
29
49
|
Class = DeprecatedClass
|
30
50
|
end
|
31
51
|
|
@@ -42,17 +62,21 @@ module Deprecator
|
|
42
62
|
@method_added_stack.push(m)
|
43
63
|
end
|
44
64
|
|
65
|
+
@skip_next_method_added_addition = true
|
45
66
|
define_singleton_method(:method_added, ->(name){
|
46
67
|
return if name == :method_added
|
47
68
|
super(name)
|
48
69
|
old = @method_added_stack.pop
|
49
70
|
if old
|
71
|
+
@skip_next_method_added_addition = true
|
50
72
|
define_singleton_method(:method_added, old)
|
73
|
+
remove_instance_variable :@skip_next_method_added_addition
|
51
74
|
else
|
52
75
|
class <<self; remove_method(:method_added); end
|
53
76
|
end
|
54
77
|
blk.call(name)
|
55
78
|
})
|
79
|
+
remove_instance_variable :@skip_next_method_added_addition
|
56
80
|
end
|
57
81
|
|
58
82
|
def deprecated_method name=nil, reason=nil, &blk
|
@@ -78,8 +102,6 @@ module Deprecator
|
|
78
102
|
|
79
103
|
DefaultStrategy = Strategy::Warning
|
80
104
|
|
81
|
-
class UnknownStrategy < ArgumentError; end
|
82
|
-
class NotImplemented < RuntimeError; end
|
83
105
|
|
84
106
|
@@strategy = nil
|
85
107
|
def self.strategy
|
data/lib/deprecator/core_ext.rb
CHANGED
data/lib/deprecator/strategy.rb
CHANGED
@@ -1,15 +1,38 @@
|
|
1
1
|
module Deprecator
|
2
2
|
module Strategy
|
3
3
|
|
4
|
-
|
5
4
|
class Base
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
#on class/module definition/extenting with deprecater or deprecate statement
|
6
|
+
def class_found cls, where=nil, reason=nil, args=nil
|
7
|
+
this = self
|
8
|
+
cls.send(:define_method, :initialize){|*args|
|
9
|
+
::Deprecator.strategy.object_found(cls, self, reason, caller_line, where)
|
10
|
+
}
|
11
|
+
|
12
|
+
cls.send(:define_singleton_method, :method_added, ->(name){
|
13
|
+
super(name)
|
14
|
+
if name == :initialize && !@skip_next_initialize_addition
|
15
|
+
meth = instance_method(name)
|
16
|
+
@skip_next_initialize_addition = true
|
17
|
+
define_method(name){|*args|
|
18
|
+
::Deprecator.strategy.object_found(cls, self, reason, caller_line, where)
|
19
|
+
meth.bind(self).call(*args)
|
20
|
+
}
|
21
|
+
remove_instance_variable :@skip_next_initialize_addition
|
22
|
+
end
|
23
|
+
})
|
24
|
+
cls.send(:define_singleton_method, :singleton_method_added, ->(name){
|
25
|
+
#guard for self?
|
26
|
+
if name == :method_added && !@skip_next_method_added_addition
|
27
|
+
warn "[WARNING] when you replace method_added for deprecated class - you can no longer autotrack its object creation, use deprecation of initialize method."
|
28
|
+
end
|
29
|
+
})
|
30
|
+
end
|
31
|
+
|
32
|
+
# on deprecated class initialize
|
33
|
+
def object_found cls, object, reason, where, deprecated_at
|
12
34
|
end
|
35
|
+
# on method definition
|
13
36
|
def method_found cls,name, reason, where=nil
|
14
37
|
this = self
|
15
38
|
unless cls.method_defined?(name) # also we may place stubs there for existing methods in other strategies
|
@@ -24,6 +47,8 @@ module Deprecator
|
|
24
47
|
}
|
25
48
|
end
|
26
49
|
end
|
50
|
+
def method_called cls,name,reason=nil,where,defined_at; end
|
51
|
+
def deprecated reason=nil, where=caller_line, args=nil; end
|
27
52
|
def fixme! msg, where, args; end
|
28
53
|
def todo! msg, where, args; end
|
29
54
|
def not_implemented msg, where, args
|
@@ -31,18 +56,20 @@ module Deprecator
|
|
31
56
|
end
|
32
57
|
end
|
33
58
|
|
59
|
+
|
60
|
+
|
34
61
|
class Warning < Base
|
35
62
|
def msg msg, where=nil
|
36
|
-
warn "[DEPRECATED] #{msg}"
|
63
|
+
warn "[DEPRECATED] #{msg}".gsub('%{where}', where)
|
37
64
|
end
|
38
65
|
|
39
|
-
def object_found
|
40
|
-
msg "deprecated class #{
|
66
|
+
def object_found cls, object, reason, where, deprecated_at # deprecated class initialize
|
67
|
+
msg "deprecated class #{cls} instantiated at %{where}", where
|
41
68
|
end
|
42
69
|
|
43
|
-
# this is not entry point
|
44
70
|
def method_called cls,name,reason=nil,where,defined_at
|
45
|
-
|
71
|
+
reason ||= "method %{method} is deprecated. Called from %{where}"
|
72
|
+
msg reason.gsub('%{method}', name.to_s), where
|
46
73
|
end
|
47
74
|
|
48
75
|
def deprecated reason=nil, where=caller_line, args=nil
|
@@ -55,5 +82,45 @@ module Deprecator
|
|
55
82
|
end
|
56
83
|
|
57
84
|
|
85
|
+
|
86
|
+
class Raise < Base
|
87
|
+
def object_found cls, object, reason, where, deprecated_at # deprecated class initialize
|
88
|
+
raise DeprecatedObjectCreated, reason || "deprecated"
|
89
|
+
end
|
90
|
+
|
91
|
+
def method_called cls,name,reason=nil,where,defined_at
|
92
|
+
reason ||= "method %{method} is deprecated."
|
93
|
+
raise DeprecatedMethodCalled, (reason || "deprecated").gsub('%{method}', name.to_s)
|
94
|
+
end
|
95
|
+
|
96
|
+
def deprecated reason=nil, where=caller_line, args=nil
|
97
|
+
where =~ /in `(.+)'$/
|
98
|
+
method_name = $1 || '<unknown>'
|
99
|
+
reason ||= "%{method} is deprecated!"
|
100
|
+
reason.gsub!('%{method}', method_name)
|
101
|
+
raise Deprecated, reason
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
class RaiseHard < Raise
|
108
|
+
def class_found cls, where=nil, reason=nil, args=nil
|
109
|
+
raise Deprecated, "#{cls} is deprecated"
|
110
|
+
end
|
111
|
+
|
112
|
+
def method_found cls,name, reason, where=nil
|
113
|
+
raise Deprecated, "#{cls}##{name} is deprecated"
|
114
|
+
end
|
115
|
+
|
116
|
+
def fixme! msg, where, args;
|
117
|
+
raise Deprecator::Fixme, msg
|
118
|
+
end
|
119
|
+
|
120
|
+
def todo! msg, where, args
|
121
|
+
raise Deprecator::Todo, msg
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
58
125
|
end
|
59
126
|
end
|
data/lib/deprecator/version.rb
CHANGED
data/spec/deprecator_spec.rb
CHANGED
@@ -46,7 +46,7 @@ describe Deprecator do
|
|
46
46
|
|
47
47
|
context "methods" do
|
48
48
|
before{
|
49
|
-
subject.strategy = :
|
49
|
+
subject.strategy = :base
|
50
50
|
}
|
51
51
|
it "simple" do
|
52
52
|
subject.strategy.should_receive(:deprecated).with("reason", duck_type(:to_s), [])
|
@@ -73,6 +73,34 @@ describe Deprecator do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
context "strategy" do
|
76
|
+
context "also installs hooks for class instantiation" do
|
77
|
+
before{ subject.strategy = :base }
|
78
|
+
it "without a reason passed" do
|
79
|
+
cls = Class.new(DEPRECATED::Class)
|
80
|
+
subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), nil, /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-1}/)
|
81
|
+
cls.new
|
82
|
+
end
|
83
|
+
|
84
|
+
it "with reason passed" do
|
85
|
+
cls = Class.new{ deprecated "reason" }
|
86
|
+
subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), "reason", /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-1}/)
|
87
|
+
cls.new
|
88
|
+
end
|
89
|
+
|
90
|
+
it "and guards for initialize method" do
|
91
|
+
cls = Class.new{
|
92
|
+
deprecated "reason"
|
93
|
+
# def self.method_added(name); puts "method added #{name}"; end
|
94
|
+
def initialize
|
95
|
+
self.class.initialize_called
|
96
|
+
end
|
97
|
+
}
|
98
|
+
cls.should_receive(:initialize_called).once
|
99
|
+
subject.strategy.should_receive(:object_found).with(cls, kind_of(cls), "reason", /#{Regexp.escape __FILE__}:#{__LINE__+1}/, /#{Regexp.escape __FILE__}:#{__LINE__-7}/)
|
100
|
+
cls.new
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
76
104
|
context "set" do
|
77
105
|
it "via object" do
|
78
106
|
obj = Object.new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deprecator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -89,6 +89,8 @@ files:
|
|
89
89
|
- README.md
|
90
90
|
- Rakefile
|
91
91
|
- deprecator.gemspec
|
92
|
+
- examples/example.rb
|
93
|
+
- examples/example2.rb
|
92
94
|
- lib/deprecator.rb
|
93
95
|
- lib/deprecator/core_ext.rb
|
94
96
|
- lib/deprecator/strategy.rb
|
@@ -116,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
118
|
version: '0'
|
117
119
|
segments:
|
118
120
|
- 0
|
119
|
-
hash:
|
121
|
+
hash: 2302177472746095841
|
120
122
|
requirements: []
|
121
123
|
rubyforge_project:
|
122
124
|
rubygems_version: 1.8.24
|