durable_decorator 0.0.9 → 0.1.0
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 +23 -7
- data/lib/durable_decorator/util.rb +20 -1
- data/lib/durable_decorator/validator.rb +16 -3
- data/lib/durable_decorator/version.rb +1 -1
- data/spec/durable_decorator_spec.rb +52 -0
- data/spec/spec_helper.rb +4 -0
- metadata +2 -2
data/README.md
CHANGED
@@ -33,7 +33,7 @@ class ExampleClass
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
ExampleClass.class_eval do
|
37
37
|
durably_decorate :string_method do
|
38
38
|
string_method_original + " and new"
|
39
39
|
end
|
@@ -62,13 +62,9 @@ Armed with this knowledge, we can enforce a strict mode:
|
|
62
62
|
```ruby
|
63
63
|
DurableDecorator::Base.determine_sha('ExampleClass#no_param_method')
|
64
64
|
# => 'ba3114b2d46caa684b3f7ba38d6f74b2'
|
65
|
-
ExampleClass.class_eval do
|
66
|
-
meta = {
|
67
|
-
mode: 'strict',
|
68
|
-
sha: 'WE-IGNORE-THE-ABOVE'
|
69
|
-
}
|
70
65
|
|
71
|
-
|
66
|
+
ExampleClass.class_eval do
|
67
|
+
durably_decorate :string_method, mode: 'strict', sha: 'ba3114b2d46caa684b3f7ba38d6f74b2' do
|
72
68
|
string_method_original + " and new"
|
73
69
|
end
|
74
70
|
end
|
@@ -76,6 +72,26 @@ end
|
|
76
72
|
DurableDecorator::TamperedDefinitionError: Method SHA mismatch, the definition has been tampered with
|
77
73
|
```
|
78
74
|
|
75
|
+
DurableDecorator may also decorate methods with params like so:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class ExampleClass
|
79
|
+
def string_method(text)
|
80
|
+
"original #{text}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
ExampleClass.class_eval do
|
85
|
+
durably_decorate :string_method, mode: 'strict', sha: 'ba3114b2d46caa684b3f7ba38d6f74b2' do |text|
|
86
|
+
string_method_original(text) + " and new"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
instance = ExampleClass.new
|
91
|
+
instance.string_method('test')
|
92
|
+
# => "original test and new"
|
93
|
+
```
|
94
|
+
|
79
95
|
DurableDecorator also maintains explicit versions of each method overriden by creating aliases with appended SHAs of the form ```some_method_1234abcd``` so you can always target explicit method versions without relying on ```some_method_original```.
|
80
96
|
|
81
97
|
DurableDecorator maintains 3 versions of aliases to previous method versions, 2 of which are short-SHA versions, akin to Github:
|
@@ -35,8 +35,27 @@ module DurableDecorator
|
|
35
35
|
def logger
|
36
36
|
return @logger if @logger
|
37
37
|
|
38
|
-
|
38
|
+
Logging.color_scheme( 'bright',
|
39
|
+
:levels => {
|
40
|
+
:info => :green,
|
41
|
+
:warn => :yellow,
|
42
|
+
:error => :red,
|
43
|
+
:fatal => [:white, :on_red]
|
44
|
+
}
|
45
|
+
)
|
46
|
+
|
47
|
+
Logging.appenders.stdout(
|
48
|
+
'stdout',
|
49
|
+
:layout => Logging.layouts.pattern(
|
50
|
+
:pattern => '%-5l %c: %m\n',
|
51
|
+
:color_scheme => 'bright'
|
52
|
+
)
|
53
|
+
)
|
54
|
+
|
55
|
+
@logger = Logging.logger['DurableDecorator']
|
39
56
|
@logger.level = :warn
|
57
|
+
|
58
|
+
Logging.logger.root.appenders = Logging.appenders.stdout
|
40
59
|
@logger
|
41
60
|
end
|
42
61
|
end
|
@@ -1,15 +1,28 @@
|
|
1
1
|
module DurableDecorator
|
2
2
|
class Validator
|
3
3
|
class << self
|
4
|
-
DECORATION_MODES = ['strict']
|
4
|
+
DECORATION_MODES = ['strict', 'soft']
|
5
5
|
|
6
6
|
def validate_decoration_meta clazz, method_name, old_method, meta
|
7
7
|
return unless meta
|
8
8
|
|
9
9
|
chill_meta = Util.symbolized_hash(meta)
|
10
|
+
provided_mode = chill_meta[:mode]
|
11
|
+
provided_sha = chill_meta[:sha]
|
12
|
+
expected_sha = Util.method_sha(old_method)
|
10
13
|
|
11
|
-
raise InvalidDecorationError, "The
|
12
|
-
raise
|
14
|
+
raise InvalidDecorationError, "The :mode provided is invalid. Possible modes are: #{DECORATION_MODES.join(", ")}" unless DECORATION_MODES.include? provided_mode
|
15
|
+
raise InvalidDecorationError, "The SHA provided appears to be empty" unless provided_sha and !provided_sha.empty?
|
16
|
+
send("handle_#{chill_meta[:mode]}_fault", clazz, method_name, expected_sha, provided_sha) unless expected_sha == provided_sha
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle_strict_fault(clazz, method_name, expected_sha, provided_sha)
|
20
|
+
raise TamperedDefinitionError, "Method SHA mismatch, the definition has been tampered with. #{expected_sha} is expected but #{provided_sha} was provided."
|
21
|
+
end
|
22
|
+
|
23
|
+
def handle_soft_fault(clazz, method_name, expected_sha, provided_sha)
|
24
|
+
Util.logger.fatal "#{clazz}##{method_name} decoration uses an invalid SHA. The original method definition could have been tampered with!"
|
25
|
+
Util.logger.fatal "Expected SHA was #{expected_sha} but the provided SHA is #{provided_sha}"
|
13
26
|
end
|
14
27
|
|
15
28
|
def validate_method_arity clazz, method_name, old_method, &block
|
@@ -125,6 +125,58 @@ describe DurableDecorator::Base do
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
128
|
+
|
129
|
+
context 'for soft definitions' do
|
130
|
+
context 'with the correct SHA' do
|
131
|
+
it 'guarantees access to #method_original' do
|
132
|
+
ExampleClass.class_eval do
|
133
|
+
meta = {
|
134
|
+
:mode => 'soft',
|
135
|
+
:sha => 'd54f9c7ea2038fac0ae2ff9af49c56f35761725d'
|
136
|
+
}
|
137
|
+
durably_decorate :no_param_method, meta do
|
138
|
+
no_param_method_original + " and a new string"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
instance = ExampleClass.new
|
143
|
+
instance.no_param_method.should == "original and a new string"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'with the wrong SHA' do
|
148
|
+
it 'logs a warning but does not raise an error' do
|
149
|
+
DurableDecorator::Util.stub(:logger).and_return(Logging.logger['SuperLogger'])
|
150
|
+
lambda{
|
151
|
+
ExampleClass.class_eval do
|
152
|
+
meta = {
|
153
|
+
:mode => 'soft',
|
154
|
+
:sha => '1234wrong'
|
155
|
+
}
|
156
|
+
durably_decorate :no_param_method, meta do
|
157
|
+
no_param_method_original + " and a new string"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
@log_output.readline.should match(/invalid SHA/)
|
161
|
+
}.should_not raise_error
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'for an invalid config' do
|
166
|
+
it 'raises an error' do
|
167
|
+
lambda{
|
168
|
+
ExampleClass.class_eval do
|
169
|
+
meta = {
|
170
|
+
:mode => 'soft'
|
171
|
+
}
|
172
|
+
durably_decorate :no_param_method, meta do
|
173
|
+
no_param_method_original + " and a new string"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
}.should raise_error(DurableDecorator::InvalidDecorationError)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
128
180
|
end
|
129
181
|
|
130
182
|
context 'for methods not yet defined' do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: durable_decorator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: method_source
|