state_mate 0.0.5 → 0.0.6
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/lib/state_mate/adapters/defaults.rb +12 -26
- data/lib/state_mate/adapters/git_config.rb +3 -2
- data/lib/state_mate/adapters/json.rb +6 -3
- data/lib/state_mate/adapters/launchd.rb +2 -0
- data/lib/state_mate/adapters/nvram.rb +5 -3
- data/lib/state_mate/adapters/pmset.rb +7 -4
- data/lib/state_mate/adapters/scutil.rb +3 -2
- data/lib/state_mate/adapters/time_machine.rb +5 -3
- data/lib/state_mate/adapters.rb +52 -0
- data/lib/state_mate/error.rb +28 -0
- data/lib/state_mate/version.rb +1 -1
- data/lib/state_mate.rb +114 -67
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a688ee124e85b425b1448494e3a59bb5244097d
|
4
|
+
data.tar.gz: e3f8f643717a325cf6743c4f690cbf4f2bc45fef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55925c3df961ce4eef5df8d88e5f4e48a53173bce138321df7f1ac9dabe54a04cefc3143821c5c7ee683806cbe388fdc4fc3bcf19b73d98b8c4c5da6a410b0c2
|
7
|
+
data.tar.gz: aec931eefee2567705e5a604bdde89be85967bf8c3c0d6f0bf7910275ebce938298ce005ab5b4e30e49ba7759783dc405698805abe1a3ce4c3119d4c9087df84
|
@@ -9,10 +9,12 @@ require 'CFPropertyList'
|
|
9
9
|
|
10
10
|
require 'cmds'
|
11
11
|
|
12
|
-
|
13
|
-
module StateMate::Adapters; end
|
12
|
+
require 'state_mate'
|
14
13
|
|
15
14
|
module StateMate::Adapters::Defaults
|
15
|
+
include StateMate::Adapters
|
16
|
+
register 'defaults'
|
17
|
+
|
16
18
|
# constants
|
17
19
|
# ========
|
18
20
|
|
@@ -43,28 +45,20 @@ module StateMate::Adapters::Defaults
|
|
43
45
|
# `nil`.
|
44
46
|
#
|
45
47
|
# @param options [Hash]
|
46
|
-
# @option options [Boolean]
|
48
|
+
# @option options [Boolean] :current_host if true, the read will be done
|
47
49
|
# for the domain's "current host" plist file (using the `-currentHost`
|
48
50
|
# option when calling the system's `defaults` command).
|
49
|
-
#
|
50
|
-
# note that the key is a {String} and not a {Symbol}.
|
51
51
|
#
|
52
52
|
# @return our Ruby representation of the value, or `nil` if it's not found.
|
53
53
|
#
|
54
54
|
def self.read key, options = {}
|
55
|
-
if options.key? :current_host
|
56
|
-
raise ArgumentError.new NRSER.squish <<-END
|
57
|
-
current_host option key must be a string, not a symbol.
|
58
|
-
END
|
59
|
-
end
|
60
|
-
|
61
55
|
options = {
|
62
|
-
|
56
|
+
current_host: false,
|
63
57
|
}.merge options
|
64
58
|
|
65
59
|
domain, key_segs = parse_key key
|
66
60
|
|
67
|
-
value = read_defaults domain, options[
|
61
|
+
value = read_defaults domain, options[:current_host]
|
68
62
|
|
69
63
|
key_segs.each do |seg|
|
70
64
|
value = if (value.is_a?(Hash) && value.key?(seg))
|
@@ -93,23 +87,15 @@ module StateMate::Adapters::Defaults
|
|
93
87
|
# key.
|
94
88
|
#
|
95
89
|
# @param options [Hash]
|
96
|
-
# @option options [Boolean]
|
90
|
+
# @option options [Boolean] :current_host if true, the read will be done
|
97
91
|
# for the domain's "current host" plist file (using the `-currentHost`
|
98
92
|
# option when calling the system's `defaults` command).
|
99
|
-
#
|
100
|
-
# note that the key is a {String} and not a {Symbol}.
|
101
93
|
#
|
102
94
|
# @return nil
|
103
95
|
#
|
104
96
|
def self.write key, value, options = {}
|
105
|
-
if options.key? :current_host
|
106
|
-
raise ArgumentError.new NRSER.squish <<-END
|
107
|
-
current_host option key must be a string, not a symbol.
|
108
|
-
END
|
109
|
-
end
|
110
|
-
|
111
97
|
options = {
|
112
|
-
|
98
|
+
current_host: false,
|
113
99
|
}.merge options
|
114
100
|
|
115
101
|
domain, key_segs = parse_key key
|
@@ -119,12 +105,12 @@ module StateMate::Adapters::Defaults
|
|
119
105
|
key_segs[0],
|
120
106
|
key_segs.drop(1),
|
121
107
|
value,
|
122
|
-
options[
|
108
|
+
options[:current_host]
|
123
109
|
else
|
124
110
|
basic_write domain,
|
125
111
|
key_segs[0],
|
126
112
|
value,
|
127
|
-
options[
|
113
|
+
options[:current_host]
|
128
114
|
end
|
129
115
|
|
130
116
|
nil
|
@@ -588,7 +574,7 @@ module StateMate::Adapters::Defaults
|
|
588
574
|
# @return nil
|
589
575
|
#
|
590
576
|
def self.deep_write domain, key, deep_segs, value, current_host
|
591
|
-
root = read [domain, key],
|
577
|
+
root = read [domain, key], current_host: current_host
|
592
578
|
# handle the root not being there
|
593
579
|
root = {} unless root.is_a? Hash
|
594
580
|
hash_deep_write! root, deep_segs, value
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'cmds'
|
2
2
|
|
3
|
-
|
4
|
-
module StateMate::Adapters; end
|
3
|
+
require 'state_mate'
|
5
4
|
|
6
5
|
# adapter to set global git config options
|
7
6
|
module StateMate::Adapters::GitConfig
|
7
|
+
include StateMate::Adapters
|
8
|
+
register 'git_config'
|
8
9
|
|
9
10
|
# @api adapter
|
10
11
|
#
|
@@ -4,6 +4,9 @@ require 'state_mate'
|
|
4
4
|
require 'state_mate/adapters/defaults'
|
5
5
|
|
6
6
|
module StateMate::Adapters::JSON
|
7
|
+
include StateMate::Adapters
|
8
|
+
register 'json'
|
9
|
+
|
7
10
|
def self.parse_key key
|
8
11
|
# use the same key seperation as Defaults
|
9
12
|
StateMate::Adapters::Defaults.parse_key key
|
@@ -14,7 +17,7 @@ module StateMate::Adapters::JSON
|
|
14
17
|
|
15
18
|
contents = File.read(File.expand_path(filepath))
|
16
19
|
|
17
|
-
value = JSON.load contents
|
20
|
+
value = ::JSON.load contents
|
18
21
|
|
19
22
|
key_segs.each do |seg|
|
20
23
|
value = if (value.is_a?(Hash) && value.key?(seg))
|
@@ -49,9 +52,9 @@ module StateMate::Adapters::JSON
|
|
49
52
|
end
|
50
53
|
|
51
54
|
content = if options['pretty']
|
52
|
-
JSON.pretty_generate new_root
|
55
|
+
::JSON.pretty_generate new_root
|
53
56
|
else
|
54
|
-
JSON.dump new_root
|
57
|
+
::JSON.dump new_root
|
55
58
|
end
|
56
59
|
|
57
60
|
File.open(filepath, 'w') do |f|
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'cmds'
|
2
2
|
require 'nrser'
|
3
3
|
|
4
|
-
|
4
|
+
require 'state_mate'
|
5
5
|
|
6
|
-
|
7
|
-
module StateMate::Adapters; end
|
6
|
+
using NRSER
|
8
7
|
|
9
8
|
module StateMate::Adapters::NVRAM
|
9
|
+
include StateMate::Adapters
|
10
|
+
register 'nvram'
|
11
|
+
|
10
12
|
def self.read key, options = {}
|
11
13
|
result = Cmds "nvram %{key}", key: key
|
12
14
|
|
@@ -1,13 +1,16 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
1
3
|
require 'cmds'
|
2
4
|
require 'nrser'
|
3
|
-
require 'pp'
|
4
5
|
|
5
|
-
|
6
|
+
require 'state_mate'
|
6
7
|
|
7
|
-
|
8
|
-
module StateMate::Adapters; end
|
8
|
+
using NRSER
|
9
9
|
|
10
10
|
module StateMate::Adapters::PMSet
|
11
|
+
include StateMate::Adapters
|
12
|
+
register 'pmset'
|
13
|
+
|
11
14
|
# whitelist of modes we handle mapped to their `pmset` flag
|
12
15
|
#
|
13
16
|
# there is also a UPS mode, but i don't know what it looks like
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'cmds'
|
2
2
|
|
3
|
-
|
4
|
-
module StateMate::Adapters; end
|
3
|
+
require 'state_mate'
|
5
4
|
|
6
5
|
# adapter to set global git config options
|
7
6
|
module StateMate::Adapters::SCUtil
|
7
|
+
include StateMate::Adapters
|
8
|
+
register 'scutil'
|
8
9
|
|
9
10
|
# @api adapter
|
10
11
|
#
|
@@ -5,12 +5,14 @@ require 'CFPropertyList'
|
|
5
5
|
require 'nrser'
|
6
6
|
require 'nrser/exec'
|
7
7
|
|
8
|
-
|
8
|
+
require 'state_mate'
|
9
9
|
|
10
|
-
|
11
|
-
module StateMate::Adapters; end
|
10
|
+
using NRSER
|
12
11
|
|
13
12
|
module StateMate::Adapters::TimeMachine
|
13
|
+
include StateMate::Adapters
|
14
|
+
register 'time_machine'
|
15
|
+
|
14
16
|
EXE = '/usr/bin/tmutil'
|
15
17
|
PLIST_PATH = '/Library/Preferences/com.apple.TimeMachine.plist'
|
16
18
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
module StateMate; end
|
4
|
+
|
5
|
+
module StateMate::Adapters
|
6
|
+
API_METHOD_NAMES = [:read, :write]
|
7
|
+
|
8
|
+
@@index = {}
|
9
|
+
|
10
|
+
module IncludeClassMethods
|
11
|
+
def register name
|
12
|
+
StateMate::Adapters.register name, self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included base
|
17
|
+
base.extend IncludeClassMethods
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.register name, obj
|
21
|
+
unless name.is_a? String
|
22
|
+
raise StateMate::Error::TypeError.new name, "name must be a String"
|
23
|
+
end
|
24
|
+
|
25
|
+
@@index[name] = obj
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.get name
|
29
|
+
# return it if it's already loaded
|
30
|
+
return @@index[name] if @@index.key? name
|
31
|
+
|
32
|
+
# try to require it
|
33
|
+
begin
|
34
|
+
require "state_mate/adapters/#{ name }"
|
35
|
+
rescue LoadError => e
|
36
|
+
end
|
37
|
+
|
38
|
+
unless @@index.key? name
|
39
|
+
raise StateMate::Error::AdapterNotFoundError.new NRSER.dedent <<-END
|
40
|
+
adapter #{ name.inspect } was not found.
|
41
|
+
|
42
|
+
registered adapters:
|
43
|
+
|
44
|
+
#{ @@index.pretty_inspect }
|
45
|
+
|
46
|
+
END
|
47
|
+
end
|
48
|
+
|
49
|
+
@@index[name]
|
50
|
+
end
|
51
|
+
|
52
|
+
end # Adapters
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module StateMate
|
2
|
+
module Error
|
3
|
+
class StateMateError < StandardError; end
|
4
|
+
|
5
|
+
class ExecutionError < StateMateError; end
|
6
|
+
|
7
|
+
class WriteError < ExecutionError; end
|
8
|
+
|
9
|
+
# raised when an erros is encountered running a sync method on an adapter
|
10
|
+
#(set, unset, array_contains, array_missing)
|
11
|
+
class ValueSyncError < ExecutionError; end
|
12
|
+
|
13
|
+
class TypeError < ::TypeError
|
14
|
+
attr_accessor :value
|
15
|
+
|
16
|
+
def initialize value, msg
|
17
|
+
@value = value
|
18
|
+
super "#{ msg }, found #{ value.inspect }"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class AdapterNotFoundError < StateMateError; end
|
23
|
+
|
24
|
+
# raised when the current structre of a value prevents the desired sync
|
25
|
+
# operation with the given options.
|
26
|
+
class StructureConflictError < StateMateError; end
|
27
|
+
end # Error
|
28
|
+
end # StateMate
|
data/lib/state_mate/version.rb
CHANGED
data/lib/state_mate.rb
CHANGED
@@ -5,33 +5,18 @@ require 'nrser/refinements'
|
|
5
5
|
using NRSER
|
6
6
|
|
7
7
|
require "state_mate/version"
|
8
|
+
require "state_mate/error"
|
9
|
+
require "state_mate/adapters"
|
8
10
|
|
9
11
|
module StateMate
|
10
12
|
|
11
13
|
DIRECTIVES = Set.new [
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
:set,
|
15
|
+
:unset,
|
16
|
+
:array_contains,
|
17
|
+
:array_missing,
|
16
18
|
]
|
17
19
|
|
18
|
-
module Error
|
19
|
-
class ExecutionError < StandardError; end
|
20
|
-
|
21
|
-
class WriteError < ExecutionError; end
|
22
|
-
|
23
|
-
class ValueChangeError < ExecutionError; end
|
24
|
-
|
25
|
-
class TypeError < ::TypeError
|
26
|
-
attr_accessor :value
|
27
|
-
|
28
|
-
def initialize value, msg
|
29
|
-
@value = value
|
30
|
-
super "#{ msg }, found #{ value.inspect }"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end # Error
|
34
|
-
|
35
20
|
class StateSet
|
36
21
|
attr_accessor :spec
|
37
22
|
attr_reader :states,
|
@@ -60,7 +45,7 @@ module StateMate
|
|
60
45
|
end
|
61
46
|
|
62
47
|
spec.each do |adapter_name, states|
|
63
|
-
adapter = StateMate.
|
48
|
+
adapter = StateMate::Adapters.get adapter_name
|
64
49
|
|
65
50
|
states = case states
|
66
51
|
when Hash
|
@@ -98,13 +83,16 @@ module StateMate
|
|
98
83
|
end
|
99
84
|
|
100
85
|
state.each do |k, v|
|
101
|
-
|
86
|
+
# normalize to symbols
|
87
|
+
k = k.to_sym if k.is_a? String
|
88
|
+
|
89
|
+
if k == :key
|
102
90
|
key = v
|
103
|
-
elsif k ==
|
91
|
+
elsif k == :options
|
104
92
|
# pass, dealt with above
|
105
93
|
elsif DIRECTIVES.include? k
|
106
94
|
directives << [k, v]
|
107
|
-
elsif k ==
|
95
|
+
elsif k == :type
|
108
96
|
type_name = v
|
109
97
|
else
|
110
98
|
# any other keys are set as options
|
@@ -181,7 +169,11 @@ module StateMate
|
|
181
169
|
test_method = StateMate.method "#{ state.directive }?"
|
182
170
|
|
183
171
|
# find out if the state is in sync
|
184
|
-
in_sync = test_method.call
|
172
|
+
in_sync = test_method.call state.key,
|
173
|
+
read_value,
|
174
|
+
state.value,
|
175
|
+
state.adapter,
|
176
|
+
state.options
|
185
177
|
|
186
178
|
# add to the list of changes to be made for states that are
|
187
179
|
# out of sync
|
@@ -205,13 +197,13 @@ module StateMate
|
|
205
197
|
state.options
|
206
198
|
rescue Exception => e
|
207
199
|
@new_value_error = e
|
208
|
-
raise Error::
|
200
|
+
raise Error::ValueSyncError.new binding.erb <<-BLOCK
|
209
201
|
an error occured when changing a values:
|
210
202
|
|
211
203
|
<%= @new_value_error.format %>
|
212
204
|
|
213
205
|
no changes were attempted to the system, so there is no rollback
|
214
|
-
|
206
|
+
necessary.
|
215
207
|
BLOCK
|
216
208
|
end
|
217
209
|
# change successful, store the new value along-side the state
|
@@ -293,39 +285,64 @@ module StateMate
|
|
293
285
|
# as strings.
|
294
286
|
#
|
295
287
|
# @param type_name [String] the 'name' of the type to cast to.
|
296
|
-
|
288
|
+
# @param value the value to cast.
|
289
|
+
#
|
297
290
|
def self.cast type_name, value
|
298
291
|
case type_name
|
299
292
|
when 'string', 'str'
|
300
293
|
value.to_s
|
301
294
|
when 'integer', 'int'
|
302
|
-
value
|
295
|
+
case value
|
296
|
+
when Fixnum
|
297
|
+
value
|
298
|
+
when true
|
299
|
+
1
|
300
|
+
when false
|
301
|
+
0
|
302
|
+
when String
|
303
|
+
if value =~ /\A[-+]?[0-9]*\Z/
|
304
|
+
value.to_i
|
305
|
+
elsif value.downcase == 'true'
|
306
|
+
1
|
307
|
+
elsif value.downcase == 'false'
|
308
|
+
0
|
309
|
+
else
|
310
|
+
raise ArgumentError.new "can't cast to integer: #{ value.inspect }"
|
311
|
+
end
|
312
|
+
else
|
313
|
+
raise TypeError.new "can't cast type to integer: #{ value.inspect }"
|
314
|
+
end
|
303
315
|
when 'float'
|
304
|
-
value
|
316
|
+
case value
|
317
|
+
when Float
|
318
|
+
value
|
319
|
+
when Fixnum
|
320
|
+
value.to_f
|
321
|
+
when String
|
322
|
+
if value =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
|
323
|
+
value.to_f
|
324
|
+
else
|
325
|
+
raise ArgumentError.new "can't cast to float: #{ value.inspect }"
|
326
|
+
end
|
327
|
+
else
|
328
|
+
raise TypeError.new "can't cast type to float: #{ value.inspect }"
|
329
|
+
end
|
305
330
|
when 'boolean', 'bool'
|
306
|
-
|
307
|
-
|
308
|
-
|
331
|
+
case value
|
332
|
+
when true, false
|
333
|
+
value
|
334
|
+
when 0, '0', 'False', 'false', 'FALSE'
|
309
335
|
false
|
310
|
-
|
311
|
-
|
336
|
+
when 1, '1', 'True', 'true', 'TRUE'
|
337
|
+
true
|
338
|
+
else
|
339
|
+
raise ArgumentError.new "can't cast type to boolean: #{ value.inspect }"
|
312
340
|
end
|
313
341
|
else
|
314
342
|
raise ArgumentError.new "bad type name: #{ type_name.inspect }"
|
315
343
|
end
|
316
344
|
end
|
317
345
|
|
318
|
-
def self.get_adapter adapter_name
|
319
|
-
begin
|
320
|
-
require "state_mate/adapters/#{ adapter_name }"
|
321
|
-
StateMate::Adapters.constants.find {|sym|
|
322
|
-
sym.to_s.downcase == adapter_name.gsub('_', '')
|
323
|
-
}.pipe {|sym| StateMate::Adapters.const_get sym}
|
324
|
-
rescue Exception => e
|
325
|
-
raise "can't find adapter #{ adapter_name.inspect }: #{ e }"
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
346
|
def self.execute spec
|
330
347
|
StateSet.from_spec(spec).execute
|
331
348
|
end
|
@@ -338,7 +355,7 @@ module StateMate
|
|
338
355
|
end
|
339
356
|
end
|
340
357
|
|
341
|
-
def self.set? key, current, value, adapter
|
358
|
+
def self.set? key, current, value, adapter, options
|
342
359
|
values_equal? current, value, adapter
|
343
360
|
end
|
344
361
|
|
@@ -347,7 +364,7 @@ module StateMate
|
|
347
364
|
value
|
348
365
|
end
|
349
366
|
|
350
|
-
def self.unset? key, current, value, adapter
|
367
|
+
def self.unset? key, current, value, adapter, options
|
351
368
|
current.nil?
|
352
369
|
end
|
353
370
|
|
@@ -357,7 +374,7 @@ module StateMate
|
|
357
374
|
nil
|
358
375
|
end
|
359
376
|
|
360
|
-
def self.array_contains? key, current, value, adapter
|
377
|
+
def self.array_contains? key, current, value, adapter, options
|
361
378
|
current.is_a?(Array) && current.any? {|v|
|
362
379
|
values_equal? v, value, adapter
|
363
380
|
}
|
@@ -366,14 +383,22 @@ module StateMate
|
|
366
383
|
def self.array_contains key, current, value, options
|
367
384
|
case current
|
368
385
|
when Array
|
369
|
-
|
386
|
+
# this is just to make the function consistent, so it doesn't add another
|
387
|
+
# copy of value if it's there... in practice StateMate should not
|
388
|
+
# call {.array_contains} if the value is alreay in the array
|
389
|
+
# (that's what {.array_contains?} tests for)
|
390
|
+
if current.include? value
|
391
|
+
current
|
392
|
+
else
|
393
|
+
current + [value]
|
394
|
+
end
|
370
395
|
|
371
396
|
when nil
|
372
397
|
# it needs to be created
|
373
|
-
if options[:create]
|
398
|
+
if options[:create] || options[:clobber]
|
374
399
|
[value]
|
375
400
|
else
|
376
|
-
raise <<-BLOCK.unblock
|
401
|
+
raise Error::StructureConflictError.new <<-BLOCK.unblock
|
377
402
|
can not ensure #{ key.inspect } contains #{ value.inspect } because
|
378
403
|
the key does not exist and options[:create] is not true.
|
379
404
|
BLOCK
|
@@ -387,18 +412,34 @@ module StateMate
|
|
387
412
|
if options[:clobber]
|
388
413
|
[value]
|
389
414
|
else
|
390
|
-
raise <<-BLOCK.unblock
|
415
|
+
raise Error::StructureConflictError.new <<-BLOCK.unblock
|
391
416
|
can not ensure #{ key.inspect } contains #{ value.inspect } because
|
392
417
|
the value is #{ current.inspect } and options[:clobber] is not true.
|
393
418
|
BLOCK
|
394
419
|
end
|
395
420
|
end # case current
|
396
421
|
end # array_contians
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
422
|
+
|
423
|
+
# @param options [Hash]
|
424
|
+
# @option options [Boolean] :unset_ok if true, the value being unset is
|
425
|
+
# acceptible. many plist files will simply omit the key rather than
|
426
|
+
# store an empty array in the case that an array value is empty,
|
427
|
+
# and setting these to an empty array when all we want to do is make
|
428
|
+
# sure that *if it is there, it doesn't contain the value* seems
|
429
|
+
# pointless.
|
430
|
+
def self.array_missing? key, current, value, adapter, options
|
431
|
+
case current
|
432
|
+
when nil
|
433
|
+
if options[:unset_ok]
|
434
|
+
true
|
435
|
+
else
|
436
|
+
false
|
437
|
+
end
|
438
|
+
when Array
|
439
|
+
!current.any? {|v| values_equal? v, value, adapter}
|
440
|
+
else
|
441
|
+
false
|
442
|
+
end
|
402
443
|
end
|
403
444
|
|
404
445
|
def self.array_missing key, current, value, options
|
@@ -407,14 +448,20 @@ module StateMate
|
|
407
448
|
current - [value]
|
408
449
|
|
409
450
|
when nil
|
410
|
-
#
|
411
|
-
|
412
|
-
|
451
|
+
# if we're ok with the value being unset (`nil` to us here), then
|
452
|
+
# we're done
|
453
|
+
if options[:unset_ok]
|
454
|
+
nil
|
413
455
|
else
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
456
|
+
# there is no value, only option is to create a new empty array there
|
457
|
+
if options[:create] || options[:clobber]
|
458
|
+
[]
|
459
|
+
else
|
460
|
+
raise Error::StructureConflictError.new <<-BLOCK.unblock
|
461
|
+
can not ensure #{ key.inspect } missing #{ value.inspect } because
|
462
|
+
the key does not exist and options[:create] is not true.
|
463
|
+
BLOCK
|
464
|
+
end
|
418
465
|
end
|
419
466
|
|
420
467
|
else
|
@@ -424,7 +471,7 @@ module StateMate
|
|
424
471
|
if options[:clobber]
|
425
472
|
[]
|
426
473
|
else
|
427
|
-
raise <<-BLOCK.unblock
|
474
|
+
raise Error::StructureConflictError.new <<-BLOCK.unblock
|
428
475
|
can not ensure #{ key.inspect } missing #{ value.inspect } because
|
429
476
|
the value is #{ current.inspect } and options[:clobber] is not true.
|
430
477
|
BLOCK
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: state_mate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nrser
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -167,6 +167,7 @@ files:
|
|
167
167
|
- ansible/library/state
|
168
168
|
- bin/console
|
169
169
|
- lib/state_mate.rb
|
170
|
+
- lib/state_mate/adapters.rb
|
170
171
|
- lib/state_mate/adapters/defaults.rb
|
171
172
|
- lib/state_mate/adapters/git_config.rb
|
172
173
|
- lib/state_mate/adapters/json.rb
|
@@ -175,6 +176,7 @@ files:
|
|
175
176
|
- lib/state_mate/adapters/pmset.rb
|
176
177
|
- lib/state_mate/adapters/scutil.rb
|
177
178
|
- lib/state_mate/adapters/time_machine.rb
|
179
|
+
- lib/state_mate/error.rb
|
178
180
|
- lib/state_mate/version.rb
|
179
181
|
- notes/state-set-steps.md
|
180
182
|
- state_mate.gemspec
|