MuranoCLI 3.0.0 → 3.0.1
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/.rubocop.yml +50 -27
- data/.trustme.vim +12 -8
- data/bin/murano +23 -8
- data/docs/basic_example.rst +1 -1
- data/docs/completions/murano_completion-bash +88 -0
- data/lib/MrMurano/Account.rb +3 -3
- data/lib/MrMurano/Business.rb +6 -6
- data/lib/MrMurano/Config-Migrate.rb +1 -3
- data/lib/MrMurano/Config.rb +16 -8
- data/lib/MrMurano/Content.rb +56 -45
- data/lib/MrMurano/Gateway.rb +62 -21
- data/lib/MrMurano/Mock.rb +27 -19
- data/lib/MrMurano/Passwords.rb +7 -7
- data/lib/MrMurano/ReCommander.rb +171 -28
- data/lib/MrMurano/Setting.rb +38 -40
- data/lib/MrMurano/Solution-ServiceConfig.rb +2 -1
- data/lib/MrMurano/Solution-Services.rb +196 -61
- data/lib/MrMurano/Solution-Users.rb +7 -7
- data/lib/MrMurano/Solution.rb +22 -8
- data/lib/MrMurano/SolutionId.rb +10 -4
- data/lib/MrMurano/SubCmdGroupContext.rb +14 -5
- data/lib/MrMurano/SyncAllowed.rb +42 -0
- data/lib/MrMurano/SyncUpDown.rb +122 -65
- data/lib/MrMurano/Webservice-Cors.rb +9 -3
- data/lib/MrMurano/Webservice-Endpoint.rb +39 -33
- data/lib/MrMurano/Webservice-File.rb +35 -24
- data/lib/MrMurano/commands/business.rb +18 -18
- data/lib/MrMurano/commands/content.rb +3 -2
- data/lib/MrMurano/commands/devices.rb +137 -22
- data/lib/MrMurano/commands/globals.rb +8 -2
- data/lib/MrMurano/commands/keystore.rb +3 -2
- data/lib/MrMurano/commands/link.rb +13 -13
- data/lib/MrMurano/commands/login.rb +3 -2
- data/lib/MrMurano/commands/mock.rb +4 -3
- data/lib/MrMurano/commands/password.rb +4 -2
- data/lib/MrMurano/commands/postgresql.rb +5 -3
- data/lib/MrMurano/commands/settings.rb +78 -62
- data/lib/MrMurano/commands/show.rb +79 -74
- data/lib/MrMurano/commands/solution.rb +6 -4
- data/lib/MrMurano/commands/solution_picker.rb +5 -4
- data/lib/MrMurano/commands/status.rb +15 -4
- data/lib/MrMurano/commands/timeseries.rb +3 -2
- data/lib/MrMurano/commands/tsdb.rb +3 -2
- data/lib/MrMurano/hash.rb +6 -6
- data/lib/MrMurano/http.rb +66 -67
- data/lib/MrMurano/makePretty.rb +18 -12
- data/lib/MrMurano/progress.rb +9 -2
- data/lib/MrMurano/verbosing.rb +14 -2
- data/lib/MrMurano/version.rb +2 -2
- data/spec/GatewayDevice_spec.rb +190 -149
- data/spec/Mock_spec.rb +3 -3
- data/spec/Solution-ServiceEventHandler_spec.rb +170 -137
- data/spec/SyncUpDown_spec.rb +205 -191
- metadata +3 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -50,7 +50,9 @@ global_option('--exclude-scopes SCOPES', Array, exclude_help) do |value|
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# --no-page is handled early on, in bin/murano.
|
53
|
-
global_option('--no-page', %(Do not page --help output))
|
53
|
+
global_option('--[no-]page', %(Do not page --help output)) do |value|
|
54
|
+
$cfg['tool.no-page'] = !value
|
55
|
+
end
|
54
56
|
|
55
57
|
global_option('--[no-]plugins', %(Do not load plugins. Good for when one goes bad))
|
56
58
|
|
@@ -58,6 +60,10 @@ global_option('--[no-]progress', %(Disable spinner and progress message)) do |va
|
|
58
60
|
$cfg['tool.no-progress'] = !value
|
59
61
|
end
|
60
62
|
|
63
|
+
global_option('--[no-]ascii', %(Use only ASCII in output)) do |value|
|
64
|
+
$cfg['tool.ascii'] = value
|
65
|
+
end
|
66
|
+
|
61
67
|
global_option('-V', '--verbose', %(Be chatty)) do
|
62
68
|
$cfg['tool.verbose'] = true
|
63
69
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -18,9 +18,10 @@ in a solution. This allows for easier debugging, being able to quickly get and
|
|
18
18
|
set data. As well as calling any of the other supported REDIS commands.
|
19
19
|
).strip
|
20
20
|
c.project_not_required = true
|
21
|
+
c.subcmdgrouphelp = true
|
21
22
|
|
22
23
|
c.action do |_args, _options|
|
23
|
-
::Commander::UI.enable_paging
|
24
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
24
25
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
25
26
|
end
|
26
27
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.23 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -13,16 +13,17 @@ require 'MrMurano/SolutionId'
|
|
13
13
|
|
14
14
|
MSG_SERVICE_LINKS_NONE_FOUND = 'No service links found' unless defined? MSG_SERVICE_LINKS_NONE_FOUND
|
15
15
|
|
16
|
-
command
|
16
|
+
command :link do |c|
|
17
17
|
c.syntax = %(murano link)
|
18
18
|
c.summary = %(Use the link commands to manage solution links)
|
19
19
|
c.description = %(
|
20
20
|
Use the link commands to manage solution links.
|
21
21
|
).strip
|
22
22
|
c.project_not_required = true
|
23
|
+
c.subcmdgrouphelp = true
|
23
24
|
|
24
25
|
c.action do |_args, _options|
|
25
|
-
::Commander::UI.enable_paging
|
26
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
26
27
|
say(MrMurano::SubCmdGroupHelp.new(c).get_help)
|
27
28
|
end
|
28
29
|
end
|
@@ -189,9 +190,8 @@ def link_solutions(sol_a, sol_b, options)
|
|
189
190
|
elsif response.is_a?(Net::HTTPConflict)
|
190
191
|
svc_cfg_exists = true
|
191
192
|
else
|
192
|
-
MrMurano::Verbose.
|
193
|
-
|
194
|
-
)
|
193
|
+
resp_msg = MrMurano::Verbose.fancy_ticks(Rainbow(response.message).underline)
|
194
|
+
MrMurano::Verbose.error("Unable to link solutions: #{resp_msg}")
|
195
195
|
sercfg.showHttpError(request, response)
|
196
196
|
end
|
197
197
|
end
|
@@ -226,9 +226,8 @@ def link_solutions(sol_a, sol_b, options)
|
|
226
226
|
elsif response.is_a?(Net::HTTPConflict)
|
227
227
|
evt_hlr_exists = true
|
228
228
|
else
|
229
|
-
MrMurano::Verbose.
|
230
|
-
|
231
|
-
)
|
229
|
+
resp_msg = MrMurano::Verbose.fancy_ticks(Rainbow(response.message).underline)
|
230
|
+
MrMurano::Verbose.error("Failed to create default event handler: #{resp_msg}")
|
232
231
|
evthlr.showHttpError(request, response)
|
233
232
|
end
|
234
233
|
end
|
@@ -264,11 +263,11 @@ def unlink_solutions(sol_a, sol_b)
|
|
264
263
|
sercfg.debug "Deleting #{svc[:service]} : #{svc[:script_key]} : #{svc[:id]}"
|
265
264
|
ret = sercfg.remove(svc[:id])
|
266
265
|
if !ret.nil?
|
267
|
-
msg = "Unlinked
|
266
|
+
msg = "Unlinked #{MrMurano::Verbose.fancy_ticks(svc[:script_key])}"
|
268
267
|
msg += " from #{sol_a.quoted_name}" unless sol_a.quoted_name.to_s.empty?
|
269
268
|
say(msg)
|
270
269
|
else
|
271
|
-
sercfg.warning "Failed to unlink
|
270
|
+
sercfg.warning "Failed to unlink #{MrMurano::Verbose.fancy_ticks(svc[:id])}"
|
272
271
|
end
|
273
272
|
end
|
274
273
|
|
@@ -289,11 +288,12 @@ def unlink_solutions(sol_a, sol_b)
|
|
289
288
|
evthlr.debug "Deleting #{evth[:service]} : #{evth[:alias]} : #{evth[:id]}"
|
290
289
|
ret = evthlr.remove(evth[:id])
|
291
290
|
if !ret.nil?
|
292
|
-
msg = "Removed
|
291
|
+
msg = "Removed #{MrMurano::Verbose.fancy_ticks(evth[:alias])}"
|
293
292
|
msg += " from #{sol_a.quoted_name}" unless sol_a.quoted_name.to_s.empty?
|
294
293
|
say(msg)
|
295
294
|
else
|
296
|
-
MrMurano::Verbose.
|
295
|
+
svc_id = MrMurano::Verbose.fancy_ticks(svc[:id])
|
296
|
+
MrMurano::Verbose.warning "Failed to remove handler #{svc_id}"
|
297
297
|
end
|
298
298
|
end
|
299
299
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.23 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -75,7 +75,8 @@ Essentially, this command is the same as:
|
|
75
75
|
cfg_val = $cfg.get(cfg_key)
|
76
76
|
if cfg_val.to_s.empty?
|
77
77
|
cfg_val = nil
|
78
|
-
MrMurano::Verbose.
|
78
|
+
cfg_key_q = MrMurano::Verbose.fancy_ticks(cfg_key)
|
79
|
+
MrMurano::Verbose.warning("No config key #{cfg_key_q}: no password to delete")
|
79
80
|
end
|
80
81
|
cfg_val
|
81
82
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -8,16 +8,17 @@
|
|
8
8
|
require 'MrMurano/Mock'
|
9
9
|
require 'MrMurano/ReCommander'
|
10
10
|
|
11
|
-
command
|
11
|
+
command :mock do |c|
|
12
12
|
c.syntax = %(murano mock)
|
13
13
|
c.summary = %(Enable or disable testpoint, or show current UUID)
|
14
14
|
c.description = %(
|
15
15
|
The mock command lets you enable testpoints to do local Lua development.
|
16
16
|
).strip
|
17
17
|
c.project_not_required = true
|
18
|
+
c.subcmdgrouphelp = true
|
18
19
|
|
19
20
|
c.action do |_args, _options|
|
20
|
-
::Commander::UI.enable_paging
|
21
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
21
22
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
22
23
|
end
|
23
24
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -14,8 +14,10 @@ command :password do |c|
|
|
14
14
|
Commands for working with usernames and passwords.
|
15
15
|
).strip
|
16
16
|
c.project_not_required = true
|
17
|
+
c.subcmdgrouphelp = true
|
18
|
+
|
17
19
|
c.action do |_args, _options|
|
18
|
-
::Commander::UI.enable_paging
|
20
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
19
21
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
20
22
|
end
|
21
23
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.23 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -125,7 +125,9 @@ extra table in your database. (__murano_cli__.migrate_version)
|
|
125
125
|
|
126
126
|
c.action do |args, options|
|
127
127
|
c.verify_arg_count!(args, 2, ['Missing direction'])
|
128
|
-
options.default(
|
128
|
+
options.default(
|
129
|
+
dir: File.join($cfg['location.base'], ($cfg['postgresql.migrations_dir'] || '')),
|
130
|
+
)
|
129
131
|
|
130
132
|
pg = MrMurano::Postgresql.new
|
131
133
|
|
@@ -135,7 +137,7 @@ extra table in your database. (__murano_cli__.migrate_version)
|
|
135
137
|
elsif direction =~ /up/i
|
136
138
|
direction = 'up'
|
137
139
|
else
|
138
|
-
pg.error "
|
140
|
+
pg.error "Unrecognized direction: #{MrMurano::Verbose.fancy_ticks(direction)}"
|
139
141
|
exit 1
|
140
142
|
end
|
141
143
|
|
@@ -1,18 +1,40 @@
|
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2016-2017 Exosite LLC.
|
5
|
+
# License: MIT. See LICENSE.txt.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
1
8
|
require 'vine'
|
2
9
|
require 'yaml'
|
3
10
|
require 'MrMurano/hash'
|
4
11
|
require 'MrMurano/ReCommander'
|
5
12
|
require 'MrMurano/Setting'
|
6
13
|
|
14
|
+
command :setting do |c|
|
15
|
+
c.syntax = %(murano setting)
|
16
|
+
c.summary = %(Use the setting commands to manage service settings)
|
17
|
+
c.description = %(
|
18
|
+
Use the setting commands to manage service settings.
|
19
|
+
).strip
|
20
|
+
c.project_not_required = true
|
21
|
+
c.subcmdgrouphelp = true
|
22
|
+
|
23
|
+
c.action do |_args, _options|
|
24
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
25
|
+
say(MrMurano::SubCmdGroupHelp.new(c).get_help)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
7
29
|
command 'setting list' do |c|
|
8
|
-
c.syntax = %
|
9
|
-
c.summary = %
|
10
|
-
c.description = %
|
11
|
-
List which services and settings are
|
12
|
-
|
30
|
+
c.syntax = %(murano setting list)
|
31
|
+
c.summary = %(List which services and settings are available)
|
32
|
+
c.description = %(
|
33
|
+
List which services and settings are available.
|
34
|
+
).strip
|
13
35
|
c.project_not_required = true
|
14
36
|
|
15
|
-
c.action do |args,
|
37
|
+
c.action do |args, _options|
|
16
38
|
c.verify_arg_count!(args)
|
17
39
|
|
18
40
|
setting = MrMurano::Setting.new
|
@@ -20,7 +42,7 @@ List which services and settings are avalible.
|
|
20
42
|
ret = setting.list
|
21
43
|
|
22
44
|
dd = []
|
23
|
-
ret.each_pair { |k,v| v.each { |s| dd << "#{k}.#{s}" } }
|
45
|
+
ret.each_pair { |k, v| v.each { |s| dd << "#{k}.#{s}" } }
|
24
46
|
|
25
47
|
setting.outf dd
|
26
48
|
end
|
@@ -28,13 +50,13 @@ end
|
|
28
50
|
alias_command 'settings list', 'setting list'
|
29
51
|
|
30
52
|
command 'setting read' do |c|
|
31
|
-
c.syntax = %
|
32
|
-
c.summary = %
|
33
|
-
c.description = %
|
53
|
+
c.syntax = %(murano setting read <service>.<setting> [<sub-key>])
|
54
|
+
c.summary = %(Read a setting on a Service)
|
55
|
+
c.description = %(
|
34
56
|
Read a setting on a Service.
|
35
|
-
|
57
|
+
).strip
|
36
58
|
|
37
|
-
c.option '-o', '--output FILE', String, %
|
59
|
+
c.option '-o', '--output FILE', String, %(File to save output to)
|
38
60
|
|
39
61
|
c.action do |args, options|
|
40
62
|
c.verify_arg_count!(args, 2, ['Missing <service>.<setting>'])
|
@@ -49,18 +71,16 @@ Read a setting on a Service.
|
|
49
71
|
ret = ret.access(subkey) unless subkey.nil?
|
50
72
|
|
51
73
|
io = nil
|
52
|
-
if options.output
|
53
|
-
io = File.open(options.output, 'w')
|
54
|
-
end
|
74
|
+
io = File.open(options.output, 'w') if options.output
|
55
75
|
setting.outf(ret, io)
|
56
76
|
io.close unless io.nil?
|
57
77
|
end
|
58
78
|
end
|
59
79
|
|
60
80
|
command 'setting write' do |c|
|
61
|
-
c.syntax = %
|
62
|
-
c.summary = %
|
63
|
-
c.description = %
|
81
|
+
c.syntax = %(murano setting write <service>.<setting> <sub-key> [<value>...])
|
82
|
+
c.summary = %(Write a setting on a Service)
|
83
|
+
c.description = %(
|
64
84
|
Write a setting on a Service, or just part of a setting.
|
65
85
|
|
66
86
|
if <value> is omitted on command line, then it is read from STDIN.
|
@@ -68,25 +88,25 @@ if <value> is omitted on command line, then it is read from STDIN.
|
|
68
88
|
This always does a read-modify-write.
|
69
89
|
|
70
90
|
If a sub-key doesn't exist, that entire path will be created as dicts.
|
71
|
-
|
91
|
+
).strip
|
72
92
|
|
73
|
-
c.option '--bool', %
|
74
|
-
c.option '--num', %
|
75
|
-
c.option '--string', %
|
76
|
-
c.option '--json', %
|
77
|
-
c.option '--array', %
|
78
|
-
c.option '--dict', %
|
93
|
+
c.option '--bool', %(Set Value type to boolean)
|
94
|
+
c.option '--num', %(Set Value type to number)
|
95
|
+
c.option '--string', %(Set Value type to string (this is default))
|
96
|
+
c.option '--json', %(Value is parsed as JSON)
|
97
|
+
c.option '--array', %(Set Value type to array of strings)
|
98
|
+
c.option '--dict', %(Set Value type to a dictionary of strings)
|
79
99
|
|
80
|
-
c.option '--append', %
|
81
|
-
c.option '--merge', %
|
100
|
+
c.option '--append', %(When sub-key is an array, append values instead of replacing)
|
101
|
+
c.option '--merge', %(When sub-key is a dict, merge values instead of replacing (child dicts are also merged))
|
82
102
|
|
83
|
-
c.example %
|
84
|
-
c.example %
|
103
|
+
c.example %(murano setting write Gateway.protocol devmode --bool yes), %()
|
104
|
+
c.example %(murano setting write Gateway.identity_format options.length --int 24), %()
|
85
105
|
|
86
|
-
c.example %
|
87
|
-
c.example %
|
106
|
+
c.example %(murano setting write Webservice.cors methods --array HEAD GET POST), %()
|
107
|
+
c.example %(murano setting write Webservice.cors headers --append --array X-My-Token), %()
|
88
108
|
|
89
|
-
c.example %
|
109
|
+
c.example %(murano setting write Webservice.cors --type=json - < ), %()
|
90
110
|
|
91
111
|
c.action do |args, options|
|
92
112
|
c.verify_arg_count!(args, nil, ['Missing <service>.<setting>', 'Missing <sub-key>'])
|
@@ -108,63 +128,61 @@ If a sub-key doesn't exist, that entire path will be created as dicts.
|
|
108
128
|
setting = MrMurano::Setting.new
|
109
129
|
|
110
130
|
# If value is '-', pull from $stdin
|
111
|
-
if value.nil?
|
112
|
-
value = $stdin.read
|
113
|
-
end
|
131
|
+
value = $stdin.read if value.nil? && args.count == 0
|
114
132
|
|
115
133
|
# Set value to correct type.
|
116
|
-
if options.bool
|
117
|
-
if value =~ /(yes|y|true|t|1|on)/i
|
134
|
+
if options.bool
|
135
|
+
if value =~ /(yes|y|true|t|1|on)/i
|
118
136
|
value = true
|
119
|
-
elsif value =~ /(no|n|false|f|0|off)/i
|
137
|
+
elsif value =~ /(no|n|false|f|0|off)/i
|
120
138
|
value = false
|
121
139
|
else
|
122
|
-
setting.error %
|
140
|
+
setting.error %(Value "#{value}" is not a bool type!)
|
123
141
|
exit 2
|
124
142
|
end
|
125
|
-
elsif options.num
|
143
|
+
elsif options.num
|
126
144
|
begin
|
127
145
|
value = Integer(value)
|
128
|
-
rescue
|
146
|
+
rescue StandardError => e
|
129
147
|
setting.debug e.to_s
|
130
148
|
begin
|
131
149
|
value = Float(value)
|
132
|
-
rescue
|
133
|
-
setting.error %
|
150
|
+
rescue StandardError => e
|
151
|
+
setting.error %(Value "#{value}" is not a number)
|
134
152
|
setting.debug e.to_s
|
135
153
|
exit 2
|
136
154
|
end
|
137
155
|
end
|
138
|
-
elsif options.json
|
156
|
+
elsif options.json
|
139
157
|
# We use the YAML parser since it will handle most common typos in json and
|
140
158
|
# product the intended output.
|
141
159
|
begin
|
142
160
|
value = YAML.load(value)
|
143
|
-
rescue
|
144
|
-
setting.error %
|
161
|
+
rescue StandardError => e
|
162
|
+
setting.error %(Value not valid JSON (or YAML))
|
145
163
|
setting.debug e.to_s
|
146
164
|
exit 2
|
147
165
|
end
|
148
166
|
|
149
|
-
elsif options.array
|
167
|
+
elsif options.array
|
150
168
|
# take remaining args as an array
|
151
169
|
value = args
|
152
170
|
|
153
|
-
elsif options.dict
|
171
|
+
elsif options.dict
|
154
172
|
# take remaining args and convert to hash
|
155
173
|
begin
|
156
174
|
value = Hash.transform_keys_to_symbols(Hash[*args])
|
157
175
|
rescue ArgumentError => e
|
158
|
-
setting.error %
|
176
|
+
setting.error %(Odd number of arguments to dictionary)
|
159
177
|
setting.debug e.to_s
|
160
178
|
exit 2
|
161
|
-
rescue
|
162
|
-
setting.error %
|
179
|
+
rescue StandardError => e
|
180
|
+
setting.error %(Cannot make dictionary from args)
|
163
181
|
setting.debug e.to_s
|
164
182
|
exit 2
|
165
183
|
end
|
166
184
|
|
167
|
-
elsif options.string
|
185
|
+
elsif options.string
|
168
186
|
value = value.to_s
|
169
187
|
else
|
170
188
|
# is a string.
|
@@ -172,32 +190,30 @@ If a sub-key doesn't exist, that entire path will be created as dicts.
|
|
172
190
|
end
|
173
191
|
|
174
192
|
ret = setting.read(service, pref)
|
175
|
-
setting.verbose %
|
193
|
+
setting.verbose %(Read value: #{ret})
|
176
194
|
|
177
195
|
# modify and merge.
|
178
|
-
if options.append
|
196
|
+
if options.append
|
179
197
|
g = ret.access(subkey)
|
180
|
-
unless g.
|
181
|
-
setting.error %
|
198
|
+
unless g.is_a? Array
|
199
|
+
setting.error %(Cannot append; "#{subkey}" is not an array.)
|
182
200
|
exit 3
|
183
201
|
end
|
184
202
|
g.push(*value)
|
185
203
|
|
186
|
-
elsif options.merge
|
204
|
+
elsif options.merge
|
187
205
|
g = ret.access(subkey)
|
188
|
-
unless g.
|
189
|
-
setting.error %
|
206
|
+
unless g.is_a? Hash
|
207
|
+
setting.error %(Cannot append; "#{subkey}" is not a dictionary.)
|
190
208
|
exit 3
|
191
209
|
end
|
192
210
|
g.deep_merge!(value)
|
193
211
|
else
|
194
212
|
ret.set(subkey, value)
|
195
213
|
end
|
196
|
-
setting.verbose %
|
214
|
+
setting.verbose %(Going to write composed value: #{ret})
|
197
215
|
|
198
216
|
setting.write(service, pref, ret)
|
199
217
|
end
|
200
218
|
end
|
201
219
|
|
202
|
-
# vim: set ai et sw=2 ts=2 :
|
203
|
-
|