super_stack 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -2
- data/lib/super_stack/layer_wrapper.rb +2 -1
- data/lib/super_stack/manager.rb +44 -10
- data/lib/super_stack/version.rb +1 -1
- data/spec/manager_spec.rb +152 -41
- data/super_stack.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54cbe4ddd3ce5e7164c09042f75841a327cd1a1c
|
4
|
+
data.tar.gz: a01f72c6e8ab135e13cf12d0f9662e1bfa6c75fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 771fcfb537611679e55a5fc36c14755ee276f71f3261190245b9299e54ec1f7fa460676f1e5a80056aa673ae9fcc9e9ab438850dd8a02c88bd3fc3aa4f64a83f
|
7
|
+
data.tar.gz: b9a855e2c8e20d9e15181ceb843da436c6b70175f96ed1deb8c0c088a67a65b6024e943e7eb265a96055ec86601195893bb262c13c68a0d81a7f5b1b66a7b64a
|
data/README.md
CHANGED
@@ -63,11 +63,11 @@ the name conflicts with another layer already handled by the manager**.
|
|
63
63
|
You can notice by the way that it gives a third way to create a layer from a hash, as when adding a hash to a manager,
|
64
64
|
it automatically adds the `SuperStack::LayerWrapper` module to the hash.
|
65
65
|
|
66
|
-
Layers can be populated from a file anytime using the `load` method:
|
66
|
+
Layers can be populated from a yaml file anytime using the `load` method:
|
67
67
|
|
68
68
|
```ruby
|
69
69
|
layer = SuperStack::Layer.new.load 'a_file_somewhere'
|
70
|
-
# Once loaded you can get the file name used to load the
|
70
|
+
# Once loaded you can get the file name used to load the layer anytime
|
71
71
|
puts layer.file_name
|
72
72
|
# And you can load or reload the layer
|
73
73
|
layer.has_file? # => true
|
@@ -89,6 +89,13 @@ manager << layer2
|
|
89
89
|
manager.reload_layers
|
90
90
|
```
|
91
91
|
|
92
|
+
Layers can of course be:
|
93
|
+
* removed (using the manager's `remove_layer(layer_or_layer_name)` method).
|
94
|
+
* Enabled or disabled (using the manager's `disable_layer(layer_or_layer_name)` and `enable_layer(layer_or_layer_name)`
|
95
|
+
methods).
|
96
|
+
|
97
|
+
Of course these methods have an impact on the `write_layer` if applied to it. Check tests (run `rspec -f d`) for
|
98
|
+
more info.
|
92
99
|
|
93
100
|
### Merge policies
|
94
101
|
|
@@ -8,7 +8,8 @@ module SuperStack
|
|
8
8
|
|
9
9
|
DEFAULT_LAYER_NAME = 'Unknown layer'
|
10
10
|
|
11
|
-
attr_reader :file_name, :priority, :manager
|
11
|
+
attr_reader :file_name, :priority, :manager, :disabled
|
12
|
+
alias_method :disabled?, :disabled
|
12
13
|
|
13
14
|
def priority=(priority)
|
14
15
|
raise 'invalid priority' unless priority.is_a? Numeric
|
data/lib/super_stack/manager.rb
CHANGED
@@ -16,14 +16,10 @@ module SuperStack
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def write_layer=(layer_or_layer_name)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
# At that point layer_or_layer_name can only contain a layer object
|
25
|
-
raise 'Invalid write layer' unless layers.values.include? layer_or_layer_name
|
26
|
-
@write_layer = layer_or_layer_name
|
19
|
+
layer = get_existing_layer layer_or_layer_name, 'Invalid write layer specified'
|
20
|
+
raise 'Cannot use a disabled layer as write layer' if layer.disabled?
|
21
|
+
@previous_write_layer = nil
|
22
|
+
@write_layer = layer
|
27
23
|
end
|
28
24
|
|
29
25
|
def []=(key,value)
|
@@ -37,8 +33,12 @@ module SuperStack
|
|
37
33
|
return layers[0] if layers.count == 1
|
38
34
|
first_layer = layers.shift
|
39
35
|
res = layers.inject(first_layer) do |stack, layer|
|
40
|
-
|
41
|
-
|
36
|
+
if layer.disabled?
|
37
|
+
stack
|
38
|
+
else
|
39
|
+
policy_to_apply = layer.merge_policy.nil? ? default_merge_policy : layer.merge_policy
|
40
|
+
policy_to_apply.merge stack, layer
|
41
|
+
end
|
42
42
|
end
|
43
43
|
if filter.nil?
|
44
44
|
# Trick to return a bare hash
|
@@ -62,11 +62,35 @@ module SuperStack
|
|
62
62
|
end
|
63
63
|
set_valid_name_for layer if layers.keys.include? layer.name
|
64
64
|
layer.priority = get_unused_priority if layer.priority.nil?
|
65
|
+
raise 'This layer already belongs to a manager' unless layer.manager.nil?
|
65
66
|
layers[layer.name] = layer
|
66
67
|
layer.instance_variable_set :@manager, self
|
67
68
|
layer.managed if layer.respond_to? :managed
|
68
69
|
end
|
69
70
|
|
71
|
+
def remove_layer(layer_or_layer_name)
|
72
|
+
layer = get_existing_layer layer_or_layer_name, 'Cannot remove unmanaged layer'
|
73
|
+
layer_name = layer.name
|
74
|
+
@write_layer = nil if layer == write_layer
|
75
|
+
layer.instance_variable_set :@manager, nil
|
76
|
+
layers.delete layer_name
|
77
|
+
end
|
78
|
+
|
79
|
+
def disable_layer(layer_or_layer_name)
|
80
|
+
layer = get_existing_layer layer_or_layer_name, 'Cannot disable unmanaged layer'
|
81
|
+
if layer == write_layer
|
82
|
+
@previous_write_layer = write_layer
|
83
|
+
@write_layer = nil
|
84
|
+
end
|
85
|
+
layer.instance_variable_set :@disabled, true
|
86
|
+
end
|
87
|
+
|
88
|
+
def enable_layer(layer_or_layer_name)
|
89
|
+
layer = get_existing_layer layer_or_layer_name, 'Cannot enable unmanaged layer'
|
90
|
+
layer.instance_variable_set :@disabled, false
|
91
|
+
@write_layer = @previous_write_layer if layer == @previous_write_layer
|
92
|
+
end
|
93
|
+
|
70
94
|
def <<(layer)
|
71
95
|
add_layer layer
|
72
96
|
end
|
@@ -77,6 +101,15 @@ module SuperStack
|
|
77
101
|
|
78
102
|
private
|
79
103
|
|
104
|
+
def get_existing_layer(layer_or_layer_name, error_message)
|
105
|
+
layer_name = layer_or_layer_name.to_s if layer_or_layer_name.is_a? Symbol
|
106
|
+
layer_name = layer_or_layer_name if layer_or_layer_name.is_a? String
|
107
|
+
layer = layers[layer_name] unless layer_name.nil?
|
108
|
+
layer = layer_or_layer_name if layer_or_layer_name.class.included_modules.include? SuperStack::LayerWrapper
|
109
|
+
raise error_message if layer.nil?
|
110
|
+
layer
|
111
|
+
end
|
112
|
+
|
80
113
|
def get_unused_priority
|
81
114
|
ordered = self.to_a
|
82
115
|
return DEFAULT_PRIORITY_INTERVAL if ordered.empty?
|
@@ -85,6 +118,7 @@ module SuperStack
|
|
85
118
|
|
86
119
|
def set_valid_name_for(layer)
|
87
120
|
name_pattern = /^(?<layer_name>.+) #(?<number>\d+)\s*$/
|
121
|
+
|
88
122
|
while layers.keys.include? layer.name
|
89
123
|
layer.name = "#{layer.name} #1" unless layer.name =~ name_pattern
|
90
124
|
layer.name.match(name_pattern) do |md|
|
data/lib/super_stack/version.rb
CHANGED
data/spec/manager_spec.rb
CHANGED
@@ -13,6 +13,11 @@ describe SuperStack::Manager do
|
|
13
13
|
layer
|
14
14
|
}
|
15
15
|
end
|
16
|
+
let(:override) {
|
17
|
+
override = SuperStack::Layer.new
|
18
|
+
override.name = :override
|
19
|
+
override
|
20
|
+
}
|
16
21
|
|
17
22
|
|
18
23
|
it 'should contain layers' do
|
@@ -71,16 +76,6 @@ describe SuperStack::Manager do
|
|
71
76
|
expect(subject.layers.keys[1] == "#{SuperStack::Layer::DEFAULT_LAYER_NAME} #2").to be_truthy
|
72
77
|
end
|
73
78
|
|
74
|
-
it 'should allow the same layer to be added multiple times, automatically changing names' do
|
75
|
-
expect {subject.add_layer(layer1) }.not_to raise_error
|
76
|
-
expect {subject.add_layer(layer1) }.not_to raise_error
|
77
|
-
expect {subject.add_layer(layer1) }.not_to raise_error
|
78
|
-
expect(subject.layers.keys.count == 3).to be_truthy
|
79
|
-
expect(subject.layers.keys[0] == 'layer1').to be_truthy
|
80
|
-
expect(subject.layers.keys[1] == 'layer1 #2').to be_truthy
|
81
|
-
expect(subject.layers.keys[2] == 'layer1 #3').to be_truthy
|
82
|
-
end
|
83
|
-
|
84
79
|
it 'should allow to reload all layers at once' do
|
85
80
|
subject.add_layer layer1
|
86
81
|
subject << {bar: :foo}
|
@@ -95,47 +90,53 @@ describe SuperStack::Manager do
|
|
95
90
|
expect(subject[:bar] == :foo).to be_truthy
|
96
91
|
end
|
97
92
|
|
98
|
-
it 'should be possible to
|
99
|
-
override = SuperStack::Layer.new
|
100
|
-
override.name = :override
|
101
|
-
subject << override
|
102
|
-
subject << layer1
|
103
|
-
expect {subject.write_layer = :override}.not_to raise_error
|
104
|
-
expect {subject.write_layer = 'override'}.not_to raise_error
|
105
|
-
expect {subject.write_layer = override}.not_to raise_error
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'should not be possible to modify if no write layer has been specified' do
|
93
|
+
it 'should not be possible to modify the manager if no write layer has been specified' do
|
109
94
|
subject << layer1
|
110
95
|
subject << layer2
|
111
96
|
expect {subject[:foo] = :bar}.to raise_error
|
112
97
|
end
|
113
98
|
|
114
|
-
|
115
|
-
override = SuperStack::Layer.new
|
116
|
-
override.name = :override
|
117
|
-
subject << override
|
118
|
-
subject << layer1
|
119
|
-
subject.write_layer = override
|
120
|
-
expect {subject[:foo] = :bar}.not_to raise_error
|
121
|
-
expect(subject.layers['override'][:foo] == :bar).to be_truthy
|
122
|
-
expect(subject[:foo] == :bar).to be_truthy
|
123
|
-
end
|
99
|
+
context 'when specifying a write layer' do
|
124
100
|
|
101
|
+
it 'should be possible using its name or itself' do
|
102
|
+
subject << override
|
103
|
+
subject << layer1
|
104
|
+
expect {subject.write_layer = :override}.not_to raise_error
|
105
|
+
expect {subject.write_layer = 'override'}.not_to raise_error
|
106
|
+
expect {subject.write_layer = override}.not_to raise_error
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should push all modifications to the write layer' do
|
110
|
+
subject << override
|
111
|
+
subject << layer1
|
112
|
+
subject.write_layer = override
|
113
|
+
expect {subject[:foo] = :bar}.not_to raise_error
|
114
|
+
expect(subject.layers['override'][:foo] == :bar).to be_truthy
|
115
|
+
expect(subject[:foo] == :bar).to be_truthy
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
it 'should be possible to clear modifications' do
|
120
|
+
subject << layer1
|
121
|
+
subject << override
|
122
|
+
subject.write_layer = override
|
123
|
+
subject[:something_modified] = :modified
|
124
|
+
expect(subject[:something_modified]).not_to be_nil
|
125
|
+
subject.reset
|
126
|
+
expect(subject[:something_modified]).to be_nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should not be possible to specify a disabled layer' do
|
130
|
+
subject << override
|
131
|
+
subject.write_layer = override
|
132
|
+
subject.disable_layer override
|
133
|
+
expect {subject.write_layer = override}.to raise_error
|
134
|
+
end
|
125
135
|
|
126
|
-
it 'should be possible to clear modifications' do
|
127
|
-
subject << layer1
|
128
|
-
override = SuperStack::Layer.new
|
129
|
-
override.name = :override
|
130
|
-
subject << override
|
131
|
-
subject.write_layer = override
|
132
|
-
subject[:something_modified] = :modified
|
133
|
-
expect(subject[:something_modified]).not_to be_nil
|
134
|
-
subject.reset
|
135
|
-
expect(subject[:something_modified]).to be_nil
|
136
136
|
end
|
137
137
|
|
138
138
|
|
139
|
+
|
139
140
|
SuperStack::MergePolicies.list.each do |policy|
|
140
141
|
it "should provide a merged view of the layers according to the merge policy: #{policy}" do
|
141
142
|
subject.add_layer layer1
|
@@ -164,4 +165,114 @@ describe SuperStack::Manager do
|
|
164
165
|
|
165
166
|
end
|
166
167
|
|
168
|
+
context 'when removing a layer' do
|
169
|
+
|
170
|
+
subject {
|
171
|
+
s = SuperStack::Manager.new
|
172
|
+
s.add_layer layer1
|
173
|
+
s.add_layer layer2
|
174
|
+
s.add_layer layer3
|
175
|
+
s.add_layer layer4
|
176
|
+
s
|
177
|
+
}
|
178
|
+
|
179
|
+
|
180
|
+
it 'should not accept an incorrect layer' do
|
181
|
+
expect {subject.remove_layer :layer12}.to raise_error
|
182
|
+
expect {subject.remove_layer nil}.to raise_error
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should accept a symbol' do
|
186
|
+
expect {subject.remove_layer :layer3}.not_to raise_error
|
187
|
+
end
|
188
|
+
it 'should accept a string' do
|
189
|
+
expect {subject.remove_layer 'layer3'}.not_to raise_error
|
190
|
+
end
|
191
|
+
it 'should accept a layer itself' do
|
192
|
+
expect {subject.remove_layer layer3}.not_to raise_error
|
193
|
+
end
|
194
|
+
it 'should not manage the layer anymore' do
|
195
|
+
subject.remove_layer :layer3
|
196
|
+
expect(layer3.manager).to be_nil
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should remain consistent in terms of merged view' do
|
200
|
+
subject.remove_layer :layer3
|
201
|
+
expect(subject[:from_layer_3]).to be_nil
|
202
|
+
expect(subject[:from_layer_1]).not_to be_nil
|
203
|
+
expect(subject[:from_layer_2]).not_to be_nil
|
204
|
+
expect(subject[:from_layer_4]).not_to be_nil
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should remain consistent regarding the write level' do
|
208
|
+
subject.write_layer = :layer3
|
209
|
+
expect(subject.write_layer == layer3).to be_truthy
|
210
|
+
subject[:foo] = :bar
|
211
|
+
expect(layer3[:foo] == :bar).to be_truthy
|
212
|
+
subject.remove_layer :layer3
|
213
|
+
expect(subject[:foo] == :bar).to be_falsey
|
214
|
+
expect(subject.write_layer).to be_nil
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'when disabling a layer' do
|
220
|
+
|
221
|
+
subject {
|
222
|
+
s = SuperStack::Manager.new
|
223
|
+
s.add_layer layer1
|
224
|
+
s.add_layer layer2
|
225
|
+
s.add_layer layer3
|
226
|
+
s.add_layer layer4
|
227
|
+
s
|
228
|
+
}
|
229
|
+
|
230
|
+
it 'should not been taken in account in the merge' do
|
231
|
+
subject.disable_layer :layer3
|
232
|
+
expect(subject[:from_layer_3]).to be_nil
|
233
|
+
expect(subject[:from_layer_1]).not_to be_nil
|
234
|
+
expect(subject[:from_layer_2]).not_to be_nil
|
235
|
+
expect(subject[:from_layer_4]).not_to be_nil
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'could be reactivated' do
|
239
|
+
subject.disable_layer :layer3
|
240
|
+
subject.enable_layer :layer3
|
241
|
+
expect(subject[:from_layer_3]).not_to be_nil
|
242
|
+
expect(subject[:from_layer_1]).not_to be_nil
|
243
|
+
expect(subject[:from_layer_2]).not_to be_nil
|
244
|
+
expect(subject[:from_layer_4]).not_to be_nil
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'when enabling/disabling a layer which is the write layer' do
|
248
|
+
subject {
|
249
|
+
s = SuperStack::Manager.new
|
250
|
+
s.add_layer layer1
|
251
|
+
s.add_layer layer2
|
252
|
+
s.add_layer layer3
|
253
|
+
s.add_layer layer4
|
254
|
+
s.write_layer = :layer3
|
255
|
+
s
|
256
|
+
}
|
257
|
+
it 'should restore it as the write layer if re-enabled' do
|
258
|
+
subject.disable_layer :layer3
|
259
|
+
expect(subject.write_layer).to be_nil
|
260
|
+
subject.enable_layer :layer3
|
261
|
+
expect(subject.write_layer).to be layer3
|
262
|
+
expect {subject[:foo] = :bar}.not_to raise_error
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'should not restore it as the write layer if another write layer has been set in between' do
|
266
|
+
subject.disable_layer :layer3
|
267
|
+
expect(subject.write_layer).to be_nil
|
268
|
+
subject.write_layer = :layer2
|
269
|
+
subject.enable_layer :layer3
|
270
|
+
expect(subject.write_layer).to be layer2
|
271
|
+
expect {subject[:foo] = :bar}.not_to raise_error
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
end
|
277
|
+
|
167
278
|
end
|
data/super_stack.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: super_stack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent B.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: deep_merge
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
75
|
+
version: '1.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
82
|
+
version: '1.0'
|
83
83
|
description: The purpose of this gem is to provide a simple way to manage the merge
|
84
84
|
of different hashes (layers) according to priority and several merge policies.
|
85
85
|
email:
|