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