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