MuranoCLI 3.2.0.beta.9 → 3.2.1.pre.beta.3
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 +3 -0
- data/Rakefile +5 -0
- data/dockers/README.rst +7 -0
- data/dockers/RELEASE.rst +6 -3
- data/dockers/docker-test.sh +45 -17
- data/docs/completions/murano_completion-bash +211 -86
- data/lib/MrMurano/Account.rb +72 -4
- data/lib/MrMurano/Business.rb +163 -2
- data/lib/MrMurano/Commander-Entry.rb +1 -2
- data/lib/MrMurano/Config.rb +19 -18
- data/lib/MrMurano/Content.rb +26 -19
- data/lib/MrMurano/Gateway.rb +51 -10
- data/lib/MrMurano/ReCommander.rb +1 -1
- data/lib/MrMurano/Solution-Services.rb +80 -35
- data/lib/MrMurano/Solution-Users.rb +1 -0
- data/lib/MrMurano/SyncRoot.rb +10 -3
- data/lib/MrMurano/SyncUpDown-Core.rb +47 -36
- data/lib/MrMurano/SyncUpDown-Item.rb +46 -14
- data/lib/MrMurano/SyncUpDown.rb +22 -20
- data/lib/MrMurano/Webservice-Endpoint.rb +20 -18
- data/lib/MrMurano/Webservice-File.rb +63 -20
- data/lib/MrMurano/commands/business.rb +14 -1
- data/lib/MrMurano/commands/child.rb +148 -0
- data/lib/MrMurano/commands/devices.rb +298 -149
- data/lib/MrMurano/commands/element.rb +2 -1
- data/lib/MrMurano/commands/globals.rb +3 -0
- data/lib/MrMurano/commands/network.rb +152 -33
- data/lib/MrMurano/commands/sync.rb +2 -2
- data/lib/MrMurano/commands.rb +1 -0
- data/lib/MrMurano/verbosing.rb +13 -2
- data/lib/MrMurano/version.rb +1 -1
- data/spec/Account_spec.rb +43 -11
- data/spec/Content_spec.rb +5 -3
- data/spec/GatewayBase_spec.rb +1 -1
- data/spec/GatewayDevice_spec.rb +47 -8
- data/spec/GatewayResource_spec.rb +1 -1
- data/spec/GatewaySettings_spec.rb +1 -1
- data/spec/HttpAuthed_spec.rb +17 -3
- data/spec/ProjectFile_spec.rb +59 -23
- data/spec/Setting_spec.rb +2 -1
- data/spec/Solution-ServiceConfig_spec.rb +1 -1
- data/spec/Solution-ServiceEventHandler_spec.rb +27 -20
- data/spec/Solution-ServiceModules_spec.rb +7 -5
- data/spec/Solution-UsersRoles_spec.rb +7 -1
- data/spec/Solution_spec.rb +9 -1
- data/spec/SyncRoot_spec.rb +5 -5
- data/spec/SyncUpDown_spec.rb +262 -211
- data/spec/Verbosing_spec.rb +49 -8
- data/spec/Webservice-Cors_spec.rb +10 -1
- data/spec/Webservice-Endpoint_spec.rb +84 -65
- data/spec/Webservice-File_spec.rb +16 -11
- data/spec/Webservice-Setting_spec.rb +7 -1
- data/spec/_workspace.rb +9 -0
- data/spec/cmd_business_spec.rb +5 -10
- data/spec/cmd_common.rb +67 -32
- data/spec/cmd_config_spec.rb +9 -14
- data/spec/cmd_content_spec.rb +15 -26
- data/spec/cmd_cors_spec.rb +9 -12
- data/spec/cmd_device_spec.rb +31 -45
- data/spec/cmd_domain_spec.rb +12 -10
- data/spec/cmd_element_spec.rb +18 -17
- data/spec/cmd_exchange_spec.rb +1 -4
- data/spec/cmd_init_spec.rb +56 -72
- data/spec/cmd_keystore_spec.rb +17 -26
- data/spec/cmd_link_spec.rb +13 -17
- data/spec/cmd_password_spec.rb +9 -10
- data/spec/cmd_setting_application_spec.rb +95 -68
- data/spec/cmd_setting_product_spec.rb +59 -37
- data/spec/cmd_status_spec.rb +46 -84
- data/spec/cmd_syncdown_application_spec.rb +28 -50
- data/spec/cmd_syncdown_both_spec.rb +44 -93
- data/spec/cmd_syncdown_unit_spec.rb +858 -0
- data/spec/cmd_syncup_spec.rb +21 -56
- data/spec/cmd_token_spec.rb +0 -3
- data/spec/cmd_usage_spec.rb +15 -10
- data/spec/dry_run_formatter.rb +1 -0
- data/spec/fixtures/dumped_config +4 -4
- data/spec/spec_helper.rb +3 -0
- metadata +4 -2
|
@@ -51,8 +51,10 @@ module MrMurano
|
|
|
51
51
|
# @example Initializing with an Item
|
|
52
52
|
# item = Item.new(:name => 'get')
|
|
53
53
|
# Item.new(item)
|
|
54
|
-
def initialize(
|
|
55
|
-
|
|
54
|
+
def initialize(hash={})
|
|
55
|
+
hash.each_pair do |key, val|
|
|
56
|
+
self[key] = val
|
|
57
|
+
end
|
|
56
58
|
end
|
|
57
59
|
|
|
58
60
|
def as_inst(key)
|
|
@@ -102,7 +104,7 @@ module MrMurano
|
|
|
102
104
|
|
|
103
105
|
# @return [Hash{Symbol=>Object}] A hash that represents this Item
|
|
104
106
|
def to_h
|
|
105
|
-
Hash[instance_variables.map { |k| [as_sym(k), instance_variable_get(k)] }]
|
|
107
|
+
Hash[instance_variables.sort.map { |k| [as_sym(k), instance_variable_get(k)] }]
|
|
106
108
|
end
|
|
107
109
|
|
|
108
110
|
# Adds the contents of item to self.
|
|
@@ -153,25 +155,38 @@ module MrMurano
|
|
|
153
155
|
dup.reject!(&block)
|
|
154
156
|
end
|
|
155
157
|
|
|
158
|
+
# Scrub local, non-BizAPI/Pegasus attrs from Item (before uploading).
|
|
159
|
+
def reject_ephemeral!
|
|
160
|
+
reject do |attr_key, _|
|
|
161
|
+
[
|
|
162
|
+
# Server-siders:
|
|
163
|
+
# :name,
|
|
164
|
+
# :script,
|
|
165
|
+
:local_path,
|
|
166
|
+
:id,
|
|
167
|
+
:line_beg,
|
|
168
|
+
:line_end,
|
|
169
|
+
:header,
|
|
170
|
+
:diff,
|
|
171
|
+
:selected,
|
|
172
|
+
:synckey,
|
|
173
|
+
:synctype,
|
|
174
|
+
:updated_at,
|
|
175
|
+
:dup_count,
|
|
176
|
+
].include? attr_key
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
156
180
|
# For unit testing.
|
|
157
181
|
include Comparable
|
|
158
182
|
def <=>(other)
|
|
159
183
|
# rubocop:disable Style/RedundantSelf: Redundant self detected.
|
|
160
|
-
# MAYBE/2017-07-18: Permanently disable Style/RedundantSelf?
|
|
161
184
|
self.to_h <=> other.to_h
|
|
162
185
|
end
|
|
163
186
|
|
|
164
187
|
def location_friendly(show_type: false, full_path: false)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
desc = desc.relative_path_from(Pathname.pwd) unless full_path
|
|
168
|
-
desc = desc.to_s
|
|
169
|
-
desc = "#{desc}:#{@line_beg}" if !@line_beg.nil? && @line_beg > 0
|
|
170
|
-
desc = "#{desc}-#{@line_end}" if !@line_end.nil? && @line_end > 0
|
|
171
|
-
else
|
|
172
|
-
desc = @synckey
|
|
173
|
-
end
|
|
174
|
-
desc += ' [phantom]' if @phantom
|
|
188
|
+
desc = location_path_and_line(full_path: full_path)
|
|
189
|
+
desc += ' [phantom]' if defined?(@phantom) && @phantom
|
|
175
190
|
return desc unless show_type
|
|
176
191
|
unless @pp_desc.to_s.empty? || (@pp_desc == @synckey)
|
|
177
192
|
desc += " (#{@pp_desc})"
|
|
@@ -180,6 +195,23 @@ module MrMurano
|
|
|
180
195
|
desc += " [#{@method} #{@path}]" if (@method && @path)
|
|
181
196
|
desc
|
|
182
197
|
end
|
|
198
|
+
|
|
199
|
+
def location_path_and_line(full_path: false)
|
|
200
|
+
if !defined?(@local_path) || @local_path.nil?
|
|
201
|
+
@synckey
|
|
202
|
+
else
|
|
203
|
+
desc = @local_path
|
|
204
|
+
desc = desc.relative_path_from(Pathname.pwd) unless full_path
|
|
205
|
+
desc = desc.to_s
|
|
206
|
+
if defined?(@line_beg) && !@line_beg.nil? && @line_beg > 0
|
|
207
|
+
desc = "#{desc}:#{@line_beg}"
|
|
208
|
+
end
|
|
209
|
+
if defined?(@line_end) && !@line_end.nil? && @line_end > 0
|
|
210
|
+
desc = "#{desc}-#{@line_end}"
|
|
211
|
+
end
|
|
212
|
+
desc
|
|
213
|
+
end
|
|
214
|
+
end
|
|
183
215
|
end
|
|
184
216
|
end
|
|
185
217
|
end
|
data/lib/MrMurano/SyncUpDown.rb
CHANGED
|
@@ -48,7 +48,7 @@ module MrMurano
|
|
|
48
48
|
# :nocov:
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def
|
|
51
|
+
def remove_or_clear(itemkey, _thereitem, _modify=false)
|
|
52
52
|
remove(itemkey)
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -88,13 +88,14 @@ module MrMurano
|
|
|
88
88
|
# @param root [Pathname,String] Root path for this resource type from config files
|
|
89
89
|
# @param path [Pathname,String] Path to local item
|
|
90
90
|
# @return [Item] hash of the details for the remote item for this path
|
|
91
|
-
def
|
|
91
|
+
def to_remote_items(root, path)
|
|
92
92
|
# This mess brought to you by Windows short path names.
|
|
93
93
|
path = Dir.glob(path.to_s).first
|
|
94
94
|
root = Dir.glob(root.to_s).first
|
|
95
95
|
path = Pathname.new(path)
|
|
96
96
|
root = Pathname.new(root)
|
|
97
|
-
Item.new(name: path.realpath.relative_path_from(root.realpath).to_s)
|
|
97
|
+
item = Item.new(name: path.realpath.relative_path_from(root.realpath).to_s)
|
|
98
|
+
[item]
|
|
98
99
|
end
|
|
99
100
|
|
|
100
101
|
##
|
|
@@ -120,7 +121,7 @@ module MrMurano
|
|
|
120
121
|
# @param item [Item] listing details for the item.
|
|
121
122
|
# @return [Pathname] path to save (or merge) remote item into
|
|
122
123
|
def tolocalpath(into, item)
|
|
123
|
-
return item[:local_path] unless item
|
|
124
|
+
return item[:local_path] unless item[:local_path].nil?
|
|
124
125
|
itemkey = @itemkey.to_sym
|
|
125
126
|
name = tolocalname(item, itemkey)
|
|
126
127
|
raise "Bad key(#{itemkey}) for #{item}" if name.nil?
|
|
@@ -188,9 +189,12 @@ module MrMurano
|
|
|
188
189
|
local.dirname.mkpath
|
|
189
190
|
local.open('wb') do |io|
|
|
190
191
|
# Do not modify remote content when diffing, e.g., do not add #ENDPOINT header.
|
|
191
|
-
untainted = options[:diff]
|
|
192
|
+
untainted = options[:diff] || false
|
|
192
193
|
fetch(id, untainted) do |chunk|
|
|
193
|
-
|
|
194
|
+
# First chunk may be header, if not part of script.
|
|
195
|
+
# Second chunk (only only chunk), is script (which may include header).
|
|
196
|
+
encoded = is_tmp && chunk || config_vars_encode(chunk)
|
|
197
|
+
io.write(encoded)
|
|
194
198
|
end
|
|
195
199
|
end
|
|
196
200
|
update_mtime(local, item)
|
|
@@ -405,7 +409,6 @@ module MrMurano
|
|
|
405
409
|
# @param from [Pathname] Directory of items to scan
|
|
406
410
|
# @return [Array<Item>] Items found
|
|
407
411
|
def localitems(from)
|
|
408
|
-
# TODO: Profile this.
|
|
409
412
|
debug "#{self.class}: Getting local items from:\n #{from}"
|
|
410
413
|
search_in = from.to_s
|
|
411
414
|
sf = searchFor.map { |i| ::File.join(search_in, i) }
|
|
@@ -416,14 +419,15 @@ module MrMurano
|
|
|
416
419
|
# about duplicate resources. I [lb] think this problem has existed
|
|
417
420
|
# but was exacerbated by the change to support sub-directory scripts
|
|
418
421
|
# (Nested Lua support).
|
|
419
|
-
|
|
422
|
+
files = Dir[*sf].collect { |path| File.absolute_path(path) }
|
|
423
|
+
files = files.uniq.flatten.compact.reject do |path|
|
|
420
424
|
if ::File.directory?(path)
|
|
421
425
|
true
|
|
422
426
|
else
|
|
423
427
|
ignoring.any? { |pattern| ignore?(path, pattern) }
|
|
424
428
|
end
|
|
425
429
|
end
|
|
426
|
-
items =
|
|
430
|
+
items = files.map do |path|
|
|
427
431
|
# Do not resolve symlinks, just relative paths (. and ..),
|
|
428
432
|
# otherwise it makes nested Lua support tricky, because
|
|
429
433
|
# symlinks might be outside the root item path, and then
|
|
@@ -433,24 +437,22 @@ module MrMurano
|
|
|
433
437
|
else
|
|
434
438
|
rpath = Pathname.new(path).expand_path
|
|
435
439
|
end
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
item.compact.map do |itm|
|
|
439
|
-
itm[:local_path] = rpath
|
|
440
|
-
itm
|
|
441
|
-
end
|
|
442
|
-
elsif !item.nil?
|
|
440
|
+
files_items = to_remote_items(from, rpath)
|
|
441
|
+
files_items.compact.map do |item|
|
|
443
442
|
item[:local_path] = rpath
|
|
444
443
|
item
|
|
445
444
|
end
|
|
446
445
|
end
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
items
|
|
446
|
+
items = items.flatten.compact.sort_by { |item| item[:local_path] }
|
|
447
|
+
debug_print_localitems(items)
|
|
448
|
+
sort_by_name(items)
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def debug_print_localitems(items)
|
|
452
|
+
return unless $cfg['tool.debug']
|
|
450
453
|
loci = items.map { |it| it.location_friendly(full_path: true) }
|
|
451
454
|
item_list = loci.sort.join("\n ")
|
|
452
455
|
debug "#{self.class}: localitems' matches:\n #{item_list}"
|
|
453
|
-
sort_by_name(items)
|
|
454
456
|
end
|
|
455
457
|
|
|
456
458
|
def ignore?(path, pattern)
|
|
@@ -25,8 +25,20 @@ module MrMurano
|
|
|
25
25
|
attr_accessor :path
|
|
26
26
|
# @return [String] Acceptable Content-Type for this endpoint
|
|
27
27
|
attr_accessor :content_type
|
|
28
|
-
#
|
|
28
|
+
# NOTE: We do not use use_basic_auth internally, but it's passed from
|
|
29
|
+
# the server, so the code actually indirectly sees it in `def []=`.
|
|
29
30
|
attr_accessor :use_basic_auth
|
|
31
|
+
|
|
32
|
+
def reject_ephemeral!
|
|
33
|
+
super.reject do |attr_key, _|
|
|
34
|
+
[
|
|
35
|
+
# Server-siders:
|
|
36
|
+
# :method,
|
|
37
|
+
# :path,
|
|
38
|
+
# :content_type,
|
|
39
|
+
].include? attr_key
|
|
40
|
+
end
|
|
41
|
+
end
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
def initialize
|
|
@@ -170,12 +182,12 @@ module MrMurano
|
|
|
170
182
|
name
|
|
171
183
|
end
|
|
172
184
|
|
|
173
|
-
def
|
|
185
|
+
def to_remote_items(_from, path)
|
|
174
186
|
# Path could be have multiple endpoints in side, so a loop.
|
|
175
|
-
items = []
|
|
176
187
|
path = Pathname.new(path) unless path.is_a? Pathname
|
|
188
|
+
items = []
|
|
177
189
|
cur = nil
|
|
178
|
-
lineno =
|
|
190
|
+
lineno = 0
|
|
179
191
|
path.readlines.each do |line|
|
|
180
192
|
lineno += 1
|
|
181
193
|
md = @match_header.match(line)
|
|
@@ -183,20 +195,8 @@ module MrMurano
|
|
|
183
195
|
# header line.
|
|
184
196
|
cur[:line_end] = lineno - 1 unless cur.nil?
|
|
185
197
|
items << cur unless cur.nil?
|
|
186
|
-
# VERIFY/2017-07-03: The syncdown test is revealing a
|
|
187
|
-
# problem with casing. The original file has a lowercase
|
|
188
|
-
# HTTP verb, e.g., "post". This is what syncup uploaded.
|
|
189
|
-
# But on murano status, the local route's method is upcased
|
|
190
|
-
# in memory, so the status command says the route is diff.
|
|
191
|
-
# But on murano diff, MurCLI makes two local temp files
|
|
192
|
-
# to execute the diff, and it also upcases the method in
|
|
193
|
-
# both files, so the diff runs clean!
|
|
194
|
-
# 2017-07-03: (lb): Adding upcase; and recreating header.
|
|
195
|
-
# 2018-06-11: (lb): Added :exclude_header to deal with
|
|
196
|
-
# service side missing header. Which isn't an error, per se.
|
|
197
198
|
script_header = "--#ENDPOINT #{md[:method].upcase} #{md[:path]}"
|
|
198
199
|
script_header += " #{md[:ctype]}" unless md[:ctype].to_s.empty?
|
|
199
|
-
script_header += "\n"
|
|
200
200
|
cur = RouteItem.new(
|
|
201
201
|
method: md[:method].upcase,
|
|
202
202
|
path: md[:path],
|
|
@@ -211,8 +211,10 @@ module MrMurano
|
|
|
211
211
|
cur[:script] += line
|
|
212
212
|
end
|
|
213
213
|
end
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
unless cur.nil?
|
|
215
|
+
cur[:line_end] = lineno
|
|
216
|
+
items << cur
|
|
217
|
+
end
|
|
216
218
|
items
|
|
217
219
|
end
|
|
218
220
|
|
|
@@ -34,6 +34,19 @@ module MrMurano
|
|
|
34
34
|
attr_accessor :md5
|
|
35
35
|
# @return [Integer] Size in bytes of the stored file.
|
|
36
36
|
attr_accessor :size
|
|
37
|
+
|
|
38
|
+
def reject_ephemeral!
|
|
39
|
+
super.reject do |attr_key, _|
|
|
40
|
+
[
|
|
41
|
+
# Server-siders:
|
|
42
|
+
# :path,
|
|
43
|
+
# :mime_type,
|
|
44
|
+
:checksum,
|
|
45
|
+
:md5,
|
|
46
|
+
:size,
|
|
47
|
+
].include? attr_key
|
|
48
|
+
end
|
|
49
|
+
end
|
|
37
50
|
end
|
|
38
51
|
|
|
39
52
|
def initialize
|
|
@@ -212,36 +225,63 @@ module MrMurano
|
|
|
212
225
|
# @param root [Pathname,String] Root path for this resource type from config files
|
|
213
226
|
# @param path [Pathname,String] Path to local item
|
|
214
227
|
# @return [Item] hash of the details for the remote item for this path
|
|
215
|
-
def
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
def to_remote_items(from, path)
|
|
229
|
+
items = super(from, path)
|
|
230
|
+
|
|
231
|
+
name = items[0][:name]
|
|
218
232
|
name = '/' if name == $cfg['files.default_page']
|
|
219
233
|
name = "/#{name}" unless name.chars.first == '/'
|
|
220
234
|
|
|
221
|
-
mime = MIME::Types.type_for(path.to_s)[0]
|
|
235
|
+
mime = MIME::Types.type_for(path.to_s)[0]
|
|
236
|
+
mime ||= MIME::Types['application/octet-stream'][0]
|
|
237
|
+
|
|
238
|
+
file_size = path.size
|
|
222
239
|
|
|
223
240
|
# FIXME/2018-04-13: (lb): When did platform switch from SHA1 to MD5?
|
|
224
241
|
# Leaving this dead code block as a reminder to verify the new
|
|
225
242
|
# behavior is the intended behavior.
|
|
226
243
|
xsum_is_sha1 = false
|
|
227
244
|
if xsum_is_sha1
|
|
228
|
-
|
|
229
|
-
# It first converts the file to hex, then takes the SHA1 of that string
|
|
230
|
-
#xsum = Digest::SHA1.file(path.to_s).hexdigest
|
|
231
|
-
xsum = Digest::SHA1.new
|
|
232
|
-
path.open('rb:ASCII-8BIT') do |io|
|
|
233
|
-
# rubocop:disable Lint/AssignmentInCondition
|
|
234
|
-
# "Assignment in condition - you probably meant to use ==."
|
|
235
|
-
while chunk = io.read(1_048_576)
|
|
236
|
-
xsum << Digest.hexencode(chunk)
|
|
237
|
-
end
|
|
238
|
-
end
|
|
245
|
+
digobj = remote_item_checksum_sha1(path)
|
|
239
246
|
else
|
|
240
|
-
|
|
247
|
+
# MD5 of the empty string is not empty (it's d41d8cd98f00b204e9800998ecf8427e)
|
|
248
|
+
# but BizAPI (or Pegasus; whomever) sends an empty string for an empty file.
|
|
249
|
+
if file_size.zero?
|
|
250
|
+
checksum = ''
|
|
251
|
+
digobj = nil
|
|
252
|
+
else
|
|
253
|
+
digobj = remote_item_checksum_md5(path)
|
|
254
|
+
end
|
|
241
255
|
end
|
|
242
|
-
debug "Checking #{name} (#{mime.simplified} #{xsum.hexdigest})"
|
|
243
256
|
|
|
244
|
-
|
|
257
|
+
checksum = digobj.hexdigest unless digobj.nil?
|
|
258
|
+
debug "Checking #{name} (#{mime.simplified} #{checksum})"
|
|
259
|
+
|
|
260
|
+
item = FileItem.new(
|
|
261
|
+
path: name,
|
|
262
|
+
mime_type: mime.simplified,
|
|
263
|
+
checksum: checksum,
|
|
264
|
+
size: file_size,
|
|
265
|
+
)
|
|
266
|
+
[item]
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def remote_item_checksum_sha1(path)
|
|
270
|
+
# NOTE: It does not actually take the SHA1 of the file. It first
|
|
271
|
+
# converts the file to hex, then takes the SHA1 of that string.
|
|
272
|
+
xsum = Digest::SHA1.new
|
|
273
|
+
path.open('rb:ASCII-8BIT') do |io|
|
|
274
|
+
# rubocop:disable Lint/AssignmentInCondition
|
|
275
|
+
# "Assignment in condition - you probably meant to use ==."
|
|
276
|
+
while chunk = io.read(1_048_576)
|
|
277
|
+
xsum << Digest.hexencode(chunk)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
xsum
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def remote_item_checksum_md5(path)
|
|
284
|
+
Digest::MD5.file(path.to_s)
|
|
245
285
|
end
|
|
246
286
|
|
|
247
287
|
# @param item [FileItem] The item to get a key from
|
|
@@ -254,8 +294,11 @@ module MrMurano
|
|
|
254
294
|
# @param item_a [FileItem]
|
|
255
295
|
# @param item_b [FileItem]
|
|
256
296
|
def docmp(item_a, item_b)
|
|
257
|
-
(
|
|
258
|
-
|
|
297
|
+
(
|
|
298
|
+
item_a[:mime_type] != item_b[:mime_type] ||
|
|
299
|
+
item_a[:checksum] != item_b[:checksum] ||
|
|
300
|
+
item_a[:size] != item_b[:size]
|
|
301
|
+
)
|
|
259
302
|
end
|
|
260
303
|
end
|
|
261
304
|
|
|
@@ -30,6 +30,13 @@ If you need to set the business ID, try some of the following:
|
|
|
30
30
|
Add the ID to the user config: #{MrMurano::EXE_NAME} config business.id <ID> --user
|
|
31
31
|
Setup a project interactively: #{MrMurano::EXE_NAME} init
|
|
32
32
|
|
|
33
|
+
- Working with enterprise network child businesses:
|
|
34
|
+
Get a list of child business IDs: #{MrMurano::EXE_NAME} network children
|
|
35
|
+
Specify the child ID explicitly #{MrMurano::EXE_NAME} <cmd> --config business.child=<ID>
|
|
36
|
+
Add the child ID to a project config: #{MrMurano::EXE_NAME} config business.child <ID>
|
|
37
|
+
Add the child ID to the user config: #{MrMurano::EXE_NAME} config business.child <ID> --user
|
|
38
|
+
|
|
39
|
+
|
|
33
40
|
).strip
|
|
34
41
|
c.project_not_required = true
|
|
35
42
|
c.subcmdgrouphelp = true
|
|
@@ -162,6 +169,9 @@ arguments. For example,
|
|
|
162
169
|
).strip
|
|
163
170
|
c.project_not_required = true
|
|
164
171
|
|
|
172
|
+
# Add --network option
|
|
173
|
+
c.option('--network')
|
|
174
|
+
|
|
165
175
|
cmd_table_output_add_options(c)
|
|
166
176
|
|
|
167
177
|
c.action do |args, options|
|
|
@@ -181,6 +191,9 @@ Find business by name or ID.
|
|
|
181
191
|
|
|
182
192
|
cmd_table_output_add_options(c)
|
|
183
193
|
|
|
194
|
+
# Add --network option
|
|
195
|
+
c.option('--network')
|
|
196
|
+
|
|
184
197
|
# Add --business/-id/-name options.
|
|
185
198
|
cmd_option_business_pickers(c)
|
|
186
199
|
|
|
@@ -325,7 +338,7 @@ def cmd_business_find_businesses(acc, args, options)
|
|
|
325
338
|
end
|
|
326
339
|
|
|
327
340
|
MrMurano::Verbose.whirly_start 'Looking for businesses...'
|
|
328
|
-
bizz = acc.businesses(bid: bid, name: name, fuzzy: fuzzy)
|
|
341
|
+
bizz = acc.businesses(bid: bid, name: name, fuzzy: fuzzy, options: options)
|
|
329
342
|
MrMurano::Verbose.whirly_stop
|
|
330
343
|
|
|
331
344
|
bizz
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
|
2
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
|
6
|
+
# Unauthorized copying of this file is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
require 'MrMurano/ReCommander'
|
|
9
|
+
|
|
10
|
+
# *** Base network command help
|
|
11
|
+
# ------------------------------
|
|
12
|
+
command :child do |c|
|
|
13
|
+
c.syntax = %(murano child)
|
|
14
|
+
c.summary = %(About child)
|
|
15
|
+
c.description = %(Commands for working with enterprise business network children.)
|
|
16
|
+
c.project_not_required = true
|
|
17
|
+
c.subcmdgrouphelp = true
|
|
18
|
+
c.action do |_args, _options|
|
|
19
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
|
20
|
+
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# View Network Child Business
|
|
25
|
+
command 'child show' do |c|
|
|
26
|
+
c.syntax = %(murano child show)
|
|
27
|
+
c.summary = %(View details about a child business in a business network.)
|
|
28
|
+
c.description = %(
|
|
29
|
+
View details about a child businesses in a business network.
|
|
30
|
+
).strip
|
|
31
|
+
c.example %(
|
|
32
|
+
View details about a child business using the parent bizid and child bizid from the config
|
|
33
|
+
).strip, 'murano child show'
|
|
34
|
+
c.example %(
|
|
35
|
+
View details about a child business in a business network using a passed in business.id and business.child
|
|
36
|
+
).strip, 'murano child show -c business.id=<PARENT_BUSINESS_ID> -c business.child=<CHILD_BUSINESS_ID>'
|
|
37
|
+
c.project_not_required = true
|
|
38
|
+
|
|
39
|
+
c.action do |_args, _options|
|
|
40
|
+
show_child
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def show_child
|
|
44
|
+
biz = MrMurano::Business.new
|
|
45
|
+
biz.must_business_id!
|
|
46
|
+
biz.must_child!
|
|
47
|
+
MrMurano::Verbose.whirly_start 'Fetching network child business...'
|
|
48
|
+
business_network = biz.get_business_network(biz.bid)
|
|
49
|
+
all_child_businesses = biz.view_child_businesses(biz.bid)
|
|
50
|
+
child_business = all_child_businesses.select { |child_biz| child_biz[:bizid] == biz.cid }[0]
|
|
51
|
+
MrMurano::Verbose.whirly_stop
|
|
52
|
+
|
|
53
|
+
puts('Business Network Name: ' + business_network[:name])
|
|
54
|
+
puts('Child Business ID: ' + child_business[:bizid])
|
|
55
|
+
puts('Child Business Name: ' + child_business[:name])
|
|
56
|
+
|
|
57
|
+
table = Terminal::Table.new
|
|
58
|
+
table.title = 'Members'
|
|
59
|
+
table.add_row %w[role email]
|
|
60
|
+
table.add_separator
|
|
61
|
+
|
|
62
|
+
child_business[:members].each do |member|
|
|
63
|
+
table.add_row [
|
|
64
|
+
member[:role],
|
|
65
|
+
member[:email],
|
|
66
|
+
]
|
|
67
|
+
end
|
|
68
|
+
puts table
|
|
69
|
+
|
|
70
|
+
return unless all_child_businesses.nil?
|
|
71
|
+
MrMurano::Verbose.error 'Error fetching network child businesses.'
|
|
72
|
+
exit 1
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Add a Member to a Network Child Business
|
|
77
|
+
command 'child add' do |c|
|
|
78
|
+
c.syntax = %(murano child add <NEW_MEMBER_EMAIL>)
|
|
79
|
+
c.summary = %(Add a member to a network child business.)
|
|
80
|
+
c.description = %(
|
|
81
|
+
Add a member to a network child business.
|
|
82
|
+
).strip
|
|
83
|
+
c.example %(
|
|
84
|
+
Add a member to a child business using the parent bizid and child bizid from the config
|
|
85
|
+
).strip, 'murano child add <NEW_MEMBER_EMAIL>'
|
|
86
|
+
c.example %(
|
|
87
|
+
Add a member to a child business using a passed in business.id and business.child
|
|
88
|
+
).strip, 'murano child add <NEW_MEMBER_EMAIL> -c business.id=<PARENT_BUSINESS_ID> -c business.child=<CHILD_BUSINESS_ID>'
|
|
89
|
+
c.project_not_required = true
|
|
90
|
+
|
|
91
|
+
c.action do |args, _options|
|
|
92
|
+
if args.empty?
|
|
93
|
+
MrMurano::Verbose.error('Please include a new member email.')
|
|
94
|
+
exit 1
|
|
95
|
+
end
|
|
96
|
+
add_member_to_child_business(args)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def add_member_to_child_business(args)
|
|
100
|
+
new_member_email = args[0]
|
|
101
|
+
biz = MrMurano::Business.new
|
|
102
|
+
biz.must_business_id!
|
|
103
|
+
biz.must_child!
|
|
104
|
+
MrMurano::Verbose.whirly_start 'Adding member to child business...'
|
|
105
|
+
response = biz.add_member_to_child_business(biz.bid, biz.cid, new_member_email)
|
|
106
|
+
MrMurano::Verbose.whirly_stop
|
|
107
|
+
return unless response.nil?
|
|
108
|
+
MrMurano::Verbose.error 'Error adding member to child business.'
|
|
109
|
+
exit(1)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Remove a Member from a Network Child Business
|
|
114
|
+
command 'child remove' do |c|
|
|
115
|
+
c.syntax = %(murano child remove <MEMBER_EMAIL>)
|
|
116
|
+
c.summary = %(Remove a member from a network child business.)
|
|
117
|
+
c.description = %(
|
|
118
|
+
Remove a member from a network child business.
|
|
119
|
+
).strip
|
|
120
|
+
c.example %(Remove a member from a child business using the parent bizid and child bizid from the config
|
|
121
|
+
).strip, 'murano child remove <MEMBER_EMAIL>'
|
|
122
|
+
c.example %(
|
|
123
|
+
Remove a member from a child business using a passed in business.id and business.child
|
|
124
|
+
).strip, 'murano child remove <MEMBER_EMAIL> -c business.id=<PARENT_BUSINESS_ID> -c business.child=<CHILD_BUSINESS_ID>'
|
|
125
|
+
c.project_not_required = true
|
|
126
|
+
|
|
127
|
+
c.action do |args, _options|
|
|
128
|
+
if args.empty?
|
|
129
|
+
MrMurano::Verbose.error('Please include a member email.')
|
|
130
|
+
exit 1
|
|
131
|
+
end
|
|
132
|
+
remove_member_from_child_business(args)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def remove_member_from_child_business(args)
|
|
136
|
+
member_email = args[0]
|
|
137
|
+
biz = MrMurano::Business.new
|
|
138
|
+
biz.must_business_id!
|
|
139
|
+
biz.must_child!
|
|
140
|
+
MrMurano::Verbose.whirly_start 'Removing member from child business...'
|
|
141
|
+
response = biz.remove_member_from_child_business(biz.bid, biz.cid, member_email)
|
|
142
|
+
MrMurano::Verbose.whirly_stop
|
|
143
|
+
return unless response.nil?
|
|
144
|
+
MrMurano::Verbose.error 'Error removing member from child business.'
|
|
145
|
+
exit(1)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|