super_stack 0.2.5 → 0.3.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.
- 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:
|