MuranoCLI 3.2.0.beta.1 → 3.2.0.beta.5
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 +4 -1
- data/.trustme.plugin +137 -0
- data/.trustme.sh +217 -117
- data/.trustme.vim +9 -3
- data/Gemfile +9 -3
- data/MuranoCLI.gemspec +8 -5
- data/Rakefile +1 -0
- data/dockers/Dockerfile.2.2.9 +6 -3
- data/dockers/Dockerfile.2.3.6 +6 -3
- data/dockers/Dockerfile.2.4.3 +6 -3
- data/dockers/Dockerfile.2.5.0 +6 -3
- data/dockers/Dockerfile.GemRelease +10 -8
- data/dockers/Dockerfile.m4 +23 -5
- data/dockers/docker-test.sh +65 -28
- data/docs/completions/murano_completion-bash +751 -57
- data/docs/develop.rst +10 -9
- data/lib/MrMurano/AccountBase.rb +95 -6
- data/lib/MrMurano/Commander-Entry.rb +9 -4
- data/lib/MrMurano/Config-Migrate.rb +2 -0
- data/lib/MrMurano/Config.rb +94 -26
- data/lib/MrMurano/Content.rb +1 -1
- data/lib/MrMurano/Exchange.rb +77 -42
- data/lib/MrMurano/Gateway.rb +1 -1
- data/lib/MrMurano/HttpAuthed.rb +20 -7
- data/lib/MrMurano/Logs.rb +10 -1
- data/lib/MrMurano/ProjectFile.rb +1 -1
- data/lib/MrMurano/ReCommander.rb +129 -73
- data/lib/MrMurano/Solution-ServiceConfig.rb +18 -11
- data/lib/MrMurano/Solution-Services.rb +78 -50
- data/lib/MrMurano/Solution-Users.rb +1 -1
- data/lib/MrMurano/Solution.rb +13 -63
- data/lib/MrMurano/SyncUpDown-Core.rb +185 -77
- data/lib/MrMurano/SyncUpDown-Item.rb +29 -4
- data/lib/MrMurano/SyncUpDown.rb +11 -11
- data/lib/MrMurano/Webservice-Cors.rb +1 -1
- data/lib/MrMurano/Webservice-Endpoint.rb +28 -17
- data/lib/MrMurano/Webservice-File.rb +103 -43
- data/lib/MrMurano/commands/domain.rb +1 -0
- data/lib/MrMurano/commands/element.rb +585 -0
- data/lib/MrMurano/commands/exchange.rb +211 -204
- data/lib/MrMurano/commands/gb.rb +1 -0
- data/lib/MrMurano/commands/globals.rb +17 -7
- data/lib/MrMurano/commands/init.rb +115 -101
- data/lib/MrMurano/commands/keystore.rb +1 -1
- data/lib/MrMurano/commands/logs.rb +2 -1
- data/lib/MrMurano/commands/postgresql.rb +17 -7
- data/lib/MrMurano/commands/service.rb +572 -0
- data/lib/MrMurano/commands/show.rb +7 -3
- data/lib/MrMurano/commands/solution.rb +2 -1
- data/lib/MrMurano/commands/solution_picker.rb +31 -15
- data/lib/MrMurano/commands/status.rb +205 -169
- data/lib/MrMurano/commands/sync.rb +70 -38
- data/lib/MrMurano/commands/token.rb +59 -14
- data/lib/MrMurano/commands/usage.rb +1 -0
- data/lib/MrMurano/commands.rb +2 -0
- data/lib/MrMurano/hash.rb +91 -0
- data/lib/MrMurano/http.rb +55 -6
- data/lib/MrMurano/makePretty.rb +47 -0
- data/lib/MrMurano/optparse.rb +60 -45
- data/lib/MrMurano/variegated/TruthyFalsey.rb +48 -0
- data/lib/MrMurano/variegated/ruby_dig.rb +64 -0
- data/lib/MrMurano/verbosing.rb +113 -3
- data/lib/MrMurano/version.rb +1 -1
- data/spec/Account_spec.rb +34 -20
- data/spec/Business_spec.rb +12 -9
- data/spec/Config_spec.rb +7 -1
- data/spec/Content_spec.rb +17 -1
- data/spec/GatewayBase_spec.rb +5 -2
- data/spec/GatewayDevice_spec.rb +4 -2
- data/spec/GatewayResource_spec.rb +4 -1
- data/spec/GatewaySettings_spec.rb +4 -1
- data/spec/HttpAuthed_spec.rb +73 -0
- data/spec/Http_spec.rb +32 -35
- data/spec/ProjectFile_spec.rb +1 -1
- data/spec/Solution-ServiceConfig_spec.rb +4 -1
- data/spec/Solution-ServiceEventHandler_spec.rb +6 -3
- data/spec/Solution-ServiceModules_spec.rb +4 -1
- data/spec/Solution-UsersRoles_spec.rb +4 -1
- data/spec/Solution_spec.rb +4 -1
- data/spec/SyncUpDown_spec.rb +1 -1
- data/spec/Webservice-Cors_spec.rb +4 -1
- data/spec/Webservice-Endpoint_spec.rb +9 -6
- data/spec/Webservice-File_spec.rb +17 -4
- data/spec/Webservice-Setting_spec.rb +6 -2
- data/spec/_workspace.rb +2 -0
- data/spec/cmd_common.rb +42 -13
- data/spec/cmd_content_spec.rb +17 -7
- data/spec/cmd_device_spec.rb +1 -1
- data/spec/cmd_domain_spec.rb +2 -2
- data/spec/cmd_element_spec.rb +400 -0
- data/spec/cmd_exchange_spec.rb +2 -2
- data/spec/cmd_init_spec.rb +59 -25
- data/spec/cmd_keystore_spec.rb +6 -3
- data/spec/cmd_link_spec.rb +10 -5
- data/spec/cmd_logs_spec.rb +1 -1
- data/spec/cmd_setting_application_spec.rb +18 -15
- data/spec/cmd_setting_product_spec.rb +7 -7
- data/spec/cmd_status_spec.rb +27 -17
- data/spec/cmd_syncdown_application_spec.rb +30 -3
- data/spec/cmd_syncdown_both_spec.rb +72 -18
- data/spec/cmd_syncup_spec.rb +71 -5
- data/spec/cmd_token_spec.rb +2 -2
- data/spec/cmd_usage_spec.rb +2 -2
- data/spec/dry_run_formatter.rb +27 -0
- data/spec/fixtures/dumped_config +8 -0
- data/spec/fixtures/exchange_element/element-show.json +1 -0
- data/spec/fixtures/exchange_element/swagger-mur-6407__10k.yaml +282 -0
- data/spec/fixtures/exchange_element/swagger-mur-6407__20k.yaml +588 -0
- data/spec/variegated_TruthyFalsey_spec.rb +29 -0
- metadata +51 -25
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# Unauthorized copying of this file is strictly prohibited.
|
|
7
7
|
|
|
8
8
|
require 'highline'
|
|
9
|
+
require 'MrMurano/makePretty'
|
|
9
10
|
require 'MrMurano/verbosing'
|
|
10
11
|
require 'MrMurano/Exchange'
|
|
11
12
|
require 'MrMurano/ReCommander'
|
|
@@ -14,261 +15,267 @@ require 'MrMurano/commands/business'
|
|
|
14
15
|
# *** Business commands: Exchange Elements
|
|
15
16
|
# ----------------------------------------
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
class ExchangeCmd
|
|
19
|
+
include MrMurano::Verbose
|
|
20
|
+
|
|
21
|
+
def command_exchange_help(cmd)
|
|
22
|
+
cmd.syntax = %(murano exchange)
|
|
23
|
+
cmd.summary = %(IoT Marketplace Exchange commands)
|
|
24
|
+
cmd.description = %(
|
|
25
|
+
Commands for working with IoT Marketplace.
|
|
26
|
+
).strip
|
|
27
|
+
cmd.project_not_required = true
|
|
28
|
+
cmd.subcmdgrouphelp = true
|
|
29
|
+
|
|
30
|
+
cmd.action do |_args, _options|
|
|
31
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
|
32
|
+
say MrMurano::SubCmdGroupHelp.new(cmd).get_help
|
|
33
|
+
end
|
|
29
34
|
end
|
|
30
|
-
end
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
def command_exchange_list(cmd)
|
|
37
|
+
cmd.syntax = %(murano exchange list [--options] [<name-or-ID>])
|
|
38
|
+
cmd.summary = %(List Exchange Elements)
|
|
39
|
+
cmd.description = %(
|
|
36
40
|
List Exchange Elements, either all of them, or those that are purchased or available.
|
|
37
41
|
|
|
38
42
|
Each Exchange Element is identified by an Element ID and a name.
|
|
39
43
|
|
|
40
44
|
Element status:
|
|
41
45
|
|
|
42
|
-
- added An Element that has been added to and enabled for your Business
|
|
46
|
+
- added An Element that has been added to and enabled for your Business
|
|
43
47
|
|
|
44
|
-
- available An Element that can be added to and enabled for your Business
|
|
48
|
+
- available An Element that can be added to and enabled for your Business
|
|
45
49
|
|
|
46
|
-
- available* An Element that you can use if you upgrade your Business tier
|
|
50
|
+
- available* An Element that you can use if you upgrade your Business tier
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
).strip
|
|
53
|
+
cmd.project_not_required = true
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
cmd_table_output_add_options(cmd)
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
cmd.option '--[no-]added', 'Only show Elements that have been added to the Business'
|
|
58
|
+
cmd.option '--[no-]elem-type', 'Show element "type"'
|
|
59
|
+
cmd.option '--[no-]full', 'Show all fields'
|
|
60
|
+
cmd.option '--[no-]other', 'Show other fields: like type, tiers, tags, and action, and apiServiceName'
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
# Add --id and --name options.
|
|
63
|
+
cmd_options_add_id_and_name(cmd)
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
cmd.action do |args, options|
|
|
66
|
+
cmd.verify_arg_count!(args, 1)
|
|
67
|
+
cmd_defaults_id_and_name(options)
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
xchg = MrMurano::Exchange.new
|
|
70
|
+
xchg.must_business_id!
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
show = elems
|
|
70
|
-
elsif options.added
|
|
71
|
-
show = purchased
|
|
72
|
-
else
|
|
73
|
-
show = available
|
|
74
|
-
end
|
|
72
|
+
show = filter_elements(xchg, options, args[0])
|
|
73
|
+
sorted = sort_elements(show)
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
headers, pruned = cmd_exchange_header_and_elems(sorted, options)
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
io = File.open(options.output, 'w') if options.output
|
|
78
|
+
xchg.outf(pruned, io) do |item, ios|
|
|
79
|
+
if options.idonly
|
|
80
|
+
ios.puts item
|
|
81
|
+
else
|
|
82
|
+
ios.puts "Found #{pruned.length} elements."
|
|
83
|
+
xchg.tabularize(
|
|
84
|
+
{
|
|
85
|
+
headers: headers.map(&:to_s),
|
|
86
|
+
rows: item,
|
|
87
|
+
},
|
|
88
|
+
ios,
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
io.close unless io.nil?
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def find_elements(xchg, options, term, skip_purchased: false)
|
|
97
|
+
filter_id = nil
|
|
98
|
+
filter_name = nil
|
|
99
|
+
filter_fuzzy = nil
|
|
100
|
+
if term
|
|
101
|
+
if options.id
|
|
102
|
+
filter_id = term
|
|
103
|
+
elsif options.name
|
|
104
|
+
filter_name = term
|
|
82
105
|
else
|
|
83
|
-
|
|
84
|
-
xchg.tabularize(
|
|
85
|
-
{
|
|
86
|
-
headers: headers.map(&:to_s),
|
|
87
|
-
rows: item,
|
|
88
|
-
},
|
|
89
|
-
ios,
|
|
90
|
-
)
|
|
106
|
+
filter_fuzzy = term
|
|
91
107
|
end
|
|
92
108
|
end
|
|
93
|
-
|
|
109
|
+
xchg.elements(
|
|
110
|
+
filter_id: filter_id,
|
|
111
|
+
filter_name: filter_name,
|
|
112
|
+
filter_fuzzy: filter_fuzzy,
|
|
113
|
+
skip_purchased: skip_purchased,
|
|
114
|
+
)
|
|
94
115
|
end
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
filter_fuzzy = nil
|
|
103
|
-
if term
|
|
104
|
-
if options.id
|
|
105
|
-
filter_id = term
|
|
106
|
-
elsif options.name
|
|
107
|
-
filter_name = term
|
|
116
|
+
|
|
117
|
+
def filter_elements(xchg, options, term)
|
|
118
|
+
elems, available, purchased = find_elements(xchg, options, term)
|
|
119
|
+
if options.added.nil?
|
|
120
|
+
elems
|
|
121
|
+
elsif options.added
|
|
122
|
+
purchased
|
|
108
123
|
else
|
|
109
|
-
|
|
124
|
+
available
|
|
110
125
|
end
|
|
111
126
|
end
|
|
112
|
-
xchg.elements(filter_id: filter_id, filter_name: filter_name, filter_fuzzy: filter_fuzzy)
|
|
113
|
-
end
|
|
114
127
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
#elems = elems.map { |elem| [elem.elementId, elem.name] }
|
|
126
|
-
elems = elems.map { |elem| headers.map { |key| elem.send(key) } }
|
|
127
|
-
elsif options.full
|
|
128
|
-
headers = %i[elementId name status type apiServiceName tiers tags actions markdown]
|
|
129
|
-
all_hdrs = (elems[0] && elems[0].meta.keys) || []
|
|
130
|
-
all_hdrs.each do |chk|
|
|
131
|
-
headers.push(chk) unless headers.include?(chk)
|
|
128
|
+
STATUSABLE_RANK = %i[added available upgrade].freeze
|
|
129
|
+
|
|
130
|
+
def sort_elements(elems)
|
|
131
|
+
elems.sort do |lhs, rhs|
|
|
132
|
+
if lhs.statusable != rhs.statusable
|
|
133
|
+
next(
|
|
134
|
+
STATUSABLE_RANK.index(lhs.statusable) <=> STATUSABLE_RANK.index(rhs.statusable)
|
|
135
|
+
)
|
|
136
|
+
end
|
|
137
|
+
lhs.name <=> rhs.name
|
|
132
138
|
end
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
#elems = elems.map { |elem| headers.map { |key| elem.send(key) } }
|
|
141
|
-
elems = elems.map do |elem|
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def cmd_exchange_header_and_elems_others(elems)
|
|
142
|
+
elems.map do |elem|
|
|
143
|
+
elem_actions = elem.actions.nil? && [] || elem.actions.map do |action|
|
|
144
|
+
action.map { |key, val| "#{key}: #{val}" }.join("\n")
|
|
145
|
+
end
|
|
142
146
|
[
|
|
143
147
|
elem.elementId,
|
|
144
148
|
elem.type,
|
|
145
149
|
elem.apiServiceName,
|
|
146
|
-
#elem.tiers,
|
|
147
|
-
#elem.tiers.join(' | '),
|
|
148
150
|
elem.tiers.join("\n"),
|
|
149
|
-
#elem.tags,
|
|
150
|
-
#elem.tags.join(' | '),
|
|
151
151
|
elem.tags.join("\n"),
|
|
152
|
-
|
|
153
|
-
elem.actions.map { |actn| actn.map { |key, val| "#{key}: #{val}" }.join("\n") }.join("\n"),
|
|
154
|
-
#elem.markdown.gsub("\n", '\\n'),
|
|
152
|
+
elem_actions.join("\n"),
|
|
155
153
|
]
|
|
156
154
|
end
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def cmd_exchange_header_and_elems_default(headers, elems, width_avail)
|
|
158
|
+
elems.map do |elem|
|
|
159
|
+
headers.map do |key|
|
|
160
|
+
full = elem.send(key)
|
|
161
|
+
next(full) if width_avail.nil? || key != :description || full.empty?
|
|
162
|
+
MrMurano::Pretties.split_text_on_whitespace(full, width_avail)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def cmd_exchange_header_and_elems(elems, options)
|
|
168
|
+
# MAYBE/2017-08-31: If you `-c outformat=json`, each Element is a
|
|
169
|
+
# list of values, rather than a dictionary. Wouldn't the JSON be
|
|
170
|
+
# easier to consume if each Element was a dict, rather than list?
|
|
171
|
+
if options.idonly
|
|
172
|
+
headers = %i[elementId]
|
|
173
|
+
elems = elems.map(&:elementId)
|
|
174
|
+
elsif options.brief
|
|
175
|
+
headers = %i[elementId name]
|
|
176
|
+
headers += [:status] unless options.added
|
|
177
|
+
elems = elems.map { |elem| headers.map { |key| elem.send(key) } }
|
|
178
|
+
elsif options.full
|
|
179
|
+
headers = %i[elementId name status type apiServiceName tiers tags actions markdown]
|
|
180
|
+
all_hdrs = (elems[0] && elems[0].meta.keys) || []
|
|
181
|
+
all_hdrs.each do |chk|
|
|
182
|
+
headers.push(chk) unless headers.include?(chk)
|
|
175
183
|
end
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
#
|
|
180
|
-
|
|
181
|
-
|
|
184
|
+
elems = elems.map { |elem| headers.map { |key| elem.send(key) || '' } }
|
|
185
|
+
elsif options.other
|
|
186
|
+
# NOTE: Showing columns not displayed when --other not specified,
|
|
187
|
+
# except not showing :markdown, ever.
|
|
188
|
+
headers = %i[elementId type apiServiceName tiers tags actions]
|
|
189
|
+
elems = cmd_exchange_header_and_elems_others(elems)
|
|
182
190
|
else
|
|
183
|
-
|
|
191
|
+
# 2017-08-28: There are 9 keys, and one of them -- :markdown -- is a
|
|
192
|
+
# lot of text, so rather than, e.g., elems[0].meta.keys, be selective.
|
|
193
|
+
headers = %i[elementId name]
|
|
194
|
+
headers += [:type] if options.elem_type
|
|
195
|
+
headers += [:status] unless options.added
|
|
196
|
+
headers += [:description]
|
|
197
|
+
width_avail = MrMurano::Pretties.width_last_column(headers, elems)
|
|
198
|
+
elems = cmd_exchange_header_and_elems_default(headers, elems, width_avail)
|
|
184
199
|
end
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
200
|
+
headers.delete(:type) if options.elem_type == false
|
|
201
|
+
[headers, elems]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def command_exchange_purchase(cmd)
|
|
205
|
+
cmd.syntax = %(murano exchange purchase [--options] <name-or-ID>)
|
|
206
|
+
cmd.summary = %(Add an Exchange Element to your Business)
|
|
207
|
+
cmd.description = %(
|
|
208
|
+
Add an Exchange Element to your Business.
|
|
209
|
+
).strip
|
|
210
|
+
# It feels a little weird to not require a project, but all
|
|
211
|
+
# we need is the Business ID; this action does not apply to
|
|
212
|
+
# solutions.
|
|
213
|
+
cmd.project_not_required = true
|
|
214
|
+
|
|
215
|
+
# Add --id and --name options.
|
|
216
|
+
cmd_options_add_id_and_name(cmd)
|
|
217
|
+
|
|
218
|
+
cmd.action do |args, options|
|
|
219
|
+
cmd.verify_arg_count!(args, 1, ['Missing Element name or ID'])
|
|
220
|
+
cmd_defaults_id_and_name(options)
|
|
221
|
+
|
|
222
|
+
xchg = MrMurano::Exchange.new
|
|
223
|
+
xchg.must_business_id!
|
|
224
|
+
|
|
225
|
+
# If the user specifies filter_id, we could try to fetch that Element
|
|
226
|
+
# directly (e.g., by calling exchange/<bizId>/element/<elemId>),
|
|
227
|
+
# but the response doesn't specify if the Element is purchased or not.
|
|
228
|
+
# So we grab everything from /element/ and /purchase/.
|
|
229
|
+
|
|
230
|
+
elems, _available, purchased = find_elements(xchg, options, args[0])
|
|
231
|
+
|
|
232
|
+
elems_must_found_one!(elems, xchg)
|
|
233
|
+
if purchased.length == 1
|
|
234
|
+
# I.e., elems.status == :added
|
|
235
|
+
xchg.warning(
|
|
236
|
+
'The specified element has already been purchased: ' \
|
|
237
|
+
"#{xchg.fancy_ticks(purchased[0].name)} (#{purchased[0].elementId})"
|
|
238
|
+
)
|
|
239
|
+
exit 2
|
|
240
|
+
elsif elems.first.status == :upgrade
|
|
241
|
+
xchg.warning('Please upgrade your Business to add this Element. Visit:')
|
|
242
|
+
xchg.warning(' https://www.exosite.io/business/settings/upgrade')
|
|
243
|
+
exit 2
|
|
212
244
|
end
|
|
245
|
+
|
|
246
|
+
xchg.purchase(elems.first.elementId)
|
|
213
247
|
end
|
|
214
248
|
end
|
|
215
|
-
[headers, elems]
|
|
216
|
-
end
|
|
217
249
|
|
|
218
|
-
|
|
219
|
-
c.syntax = %(murano exchange purchase [--options] <name-or-ID>)
|
|
220
|
-
c.summary = %(Add an Exchange Element to your Business)
|
|
221
|
-
c.description = %(
|
|
222
|
-
Add an Exchange Element to your Business.
|
|
223
|
-
).strip
|
|
224
|
-
# It feels a little weird to not require a project, but all
|
|
225
|
-
# we need is the Business ID; this action does not apply to
|
|
226
|
-
# solutions.
|
|
227
|
-
c.project_not_required = true
|
|
228
|
-
|
|
229
|
-
# Add --id and --name options.
|
|
230
|
-
cmd_options_add_id_and_name(c)
|
|
231
|
-
|
|
232
|
-
c.action do |args, options|
|
|
233
|
-
c.verify_arg_count!(args, 1, ['Missing Element name or ID'])
|
|
234
|
-
cmd_defaults_id_and_name(options)
|
|
235
|
-
|
|
236
|
-
xchg = MrMurano::Exchange.new
|
|
237
|
-
xchg.must_business_id!
|
|
238
|
-
|
|
239
|
-
# If the user specifies filter_id, we could try to fetch that Element
|
|
240
|
-
# directly (e.g., by calling exchange/<bizId>/element/<elemId>),
|
|
241
|
-
# but the response doesn't specify if the Element is purchased or not.
|
|
242
|
-
# So we grab everything from /element/ and /purchase/.
|
|
243
|
-
|
|
244
|
-
elems, _available, purchased = find_elements(xchg, options, args[0])
|
|
250
|
+
def elems_must_found_one!(elems, xchg)
|
|
245
251
|
if elems.length > 1
|
|
246
|
-
idents = elems.map { |elem| "#{xchg.fancy_ticks(elem.name)}
|
|
247
|
-
idents[-1] = 'and ' + idents[-1]
|
|
252
|
+
idents = elems.map { |elem| "#{elem.elementId}: #{xchg.fancy_ticks(elem.name)}" }
|
|
248
253
|
xchg.warning(
|
|
249
|
-
|
|
250
|
-
"#{idents.join(
|
|
254
|
+
"Please be more specific: More than one matching element was found:\n " \
|
|
255
|
+
"#{idents.join("\n ")}"
|
|
251
256
|
)
|
|
252
257
|
exit 2
|
|
253
258
|
elsif elems.empty?
|
|
254
259
|
xchg.warning('No matching element was found.')
|
|
255
260
|
exit 2
|
|
256
|
-
elsif purchased.length == 1
|
|
257
|
-
# I.e., elems.status == :added
|
|
258
|
-
xchg.warning(
|
|
259
|
-
'The specified element has already been purchased: ' \
|
|
260
|
-
"#{xchg.fancy_ticks(purchased[0].name)} (#{purchased[0].elementId})"
|
|
261
|
-
)
|
|
262
|
-
exit 2
|
|
263
|
-
elsif elems.first.status == :upgrade
|
|
264
|
-
xchg.warning('Please upgrade your Business to add this Element. Visit:')
|
|
265
|
-
xchg.warning(' https://www.exosite.io/business/settings/upgrade')
|
|
266
|
-
exit 2
|
|
267
261
|
end
|
|
268
|
-
|
|
269
|
-
xchg.purchase(elems.first.elementId)
|
|
262
|
+
elems.first
|
|
270
263
|
end
|
|
271
264
|
end
|
|
272
|
-
|
|
273
|
-
|
|
265
|
+
|
|
266
|
+
def wire_cmd_exchange
|
|
267
|
+
exchange_cmd = ExchangeCmd.new
|
|
268
|
+
|
|
269
|
+
command(:exchange) { |cmd| exchange_cmd.command_exchange_help(cmd) }
|
|
270
|
+
|
|
271
|
+
command('exchange list') { |cmd| exchange_cmd.command_exchange_list(cmd) }
|
|
272
|
+
alias_command 'exchange list available', 'exchange list', '--no-added'
|
|
273
|
+
alias_command 'exchange list purchased', 'exchange list', '--added'
|
|
274
|
+
|
|
275
|
+
command('exchange purchase') { |cmd| exchange_cmd.command_exchange_purchase(cmd) }
|
|
276
|
+
alias_command 'exchange add', 'exchange purchase'
|
|
277
|
+
alias_command 'exchange buy', 'exchange purchase'
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
wire_cmd_exchange
|
|
274
281
|
|
data/lib/MrMurano/commands/gb.rb
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
require 'MrMurano/verbosing'
|
|
9
9
|
require 'MrMurano/Config'
|
|
10
|
+
require 'MrMurano/variegated/TruthyFalsey'
|
|
10
11
|
|
|
11
12
|
global_option('--[no-]color', %(Disable fancy output)) do |value|
|
|
12
13
|
HighLine.use_color = value
|
|
@@ -14,16 +15,20 @@ global_option('--[no-]color', %(Disable fancy output)) do |value|
|
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
global_option('-c', '--config KEY=VALUE', %(Set a single config key)) do |param|
|
|
18
|
+
# a=b :> ['a', 'b']
|
|
19
|
+
# a= :> ['a', '']
|
|
20
|
+
# a :> ['a', nil]
|
|
17
21
|
key, value = param.split('=', 2)
|
|
18
|
-
# a=b :> ["a", "b"]
|
|
19
|
-
# a= :> ["a", ""]
|
|
20
|
-
# a :> ["a"]
|
|
21
22
|
raise "Bad config '#{param}'" if key.nil?
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
section, ikey = key.split('.', 2)
|
|
24
|
+
if ikey.nil?
|
|
25
|
+
ikey = section
|
|
26
|
+
section = 'tool'
|
|
27
|
+
key = "#{section}.#{ikey}"
|
|
26
28
|
end
|
|
29
|
+
# If existing config setting is a boolean, coerce value as such,
|
|
30
|
+
# rather than setting a string, e.g., false, not "false".
|
|
31
|
+
$cfg[key] = TruthyFalsey.coerce_boolean(value, $cfg[key])
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
global_option('-C', '--configfile FILE', %(Load additional configuration file)) do |file|
|
|
@@ -89,6 +94,11 @@ global_option('--debug', %(Show debug messages)) do
|
|
|
89
94
|
$cfg['tool.debug'] = true
|
|
90
95
|
end
|
|
91
96
|
|
|
97
|
+
# 2018-04-24: (lb): Let's *not* advertise this, shall we?
|
|
98
|
+
# global_option('--developer', %(Enable developer mode)) do
|
|
99
|
+
# $cfg['tool.developer'] = true
|
|
100
|
+
# end
|
|
101
|
+
|
|
92
102
|
global_option('--sid VALUE', %(Override application or product ID)) do |value|
|
|
93
103
|
$cfg['application.id'] = value
|
|
94
104
|
$cfg['product.id'] = value
|