durable_decorator 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|