deprecator 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|