MuranoCLI 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,11 +24,6 @@ module MrMurano
24
24
  # :nocov:
25
25
  end
26
26
 
27
- def list
28
- ret = get()
29
- ret[:items]
30
- end
31
-
32
27
  def fetch(name)
33
28
  raise "Missing name!" if name.nil?
34
29
  raise "Empty name!" if name.empty?
@@ -55,7 +50,7 @@ module MrMurano
55
50
  # we assume these are small enough to slurp.
56
51
  script = local.read
57
52
 
58
- pst = remote.merge ({
53
+ pst = remote.to_h.merge ({
59
54
  :solution_id => $cfg['solution.id'],
60
55
  :script => script,
61
56
  :alias=>mkalias(remote),
@@ -152,8 +147,20 @@ module MrMurano
152
147
  end
153
148
  end
154
149
 
155
- # …/library
150
+ # Libraries or better known as Modules.
156
151
  class Library < ServiceBase
152
+ # Module Specific details on an Item
153
+ class LibraryItem < Item
154
+ # @return [String] Internal Alias name
155
+ attr_accessor :alias
156
+ # @return [String] Timestamp when this was updated.
157
+ attr_accessor :updated_at
158
+ # @return [String] Timestamp when this was created.
159
+ attr_accessor :created_at
160
+ # @return [String] The solution.id that this is in
161
+ attr_accessor :solution_id
162
+ end
163
+
157
164
  def initialize
158
165
  super
159
166
  @uriparts << 'library'
@@ -167,24 +174,30 @@ module MrMurano
167
174
  end
168
175
 
169
176
  def mkalias(remote)
170
- if remote.has_key? :name then
177
+ unless remote.name.nil? then
171
178
  [$cfg['solution.id'], remote[:name]].join('_')
172
179
  else
173
- raise "Missing parts! #{remote.to_json}"
180
+ raise "Missing parts! #{remote.to_h.to_json}"
174
181
  end
175
182
  end
176
183
 
177
184
  def mkname(remote)
178
- if remote.has_key? :name then
185
+ unless remote.name.nil? then
179
186
  remote[:name]
180
187
  else
181
- raise "Missing parts! #{remote.to_json}"
188
+ raise "Missing parts! #{remote.to_h.to_json}"
182
189
  end
183
190
  end
184
191
 
192
+ def list
193
+ ret = get()
194
+ return [] unless ret.has_key? :items
195
+ ret[:items].map{|i| LibraryItem.new(i)}
196
+ end
197
+
185
198
  def toRemoteItem(from, path)
186
199
  name = path.basename.to_s.sub(/\..*/, '')
187
- {:name => name}
200
+ LibraryItem.new(:name => name)
188
201
  end
189
202
 
190
203
  def synckey(item)
@@ -193,8 +206,24 @@ module MrMurano
193
206
  end
194
207
  SyncRoot.add('modules', Library, 'M', %{Modules}, true)
195
208
 
196
- # …/eventhandler
209
+ # Services aka EventHandlers
197
210
  class EventHandler < ServiceBase
211
+ # EventHandler Specific details on an Item
212
+ class EventHandlerItem < Item
213
+ # @return [String] Internal Alias name
214
+ attr_accessor :alias
215
+ # @return [String] Timestamp when this was updated.
216
+ attr_accessor :updated_at
217
+ # @return [String] Timestamp when this was created.
218
+ attr_accessor :created_at
219
+ # @return [String] The solution.id that this is in
220
+ attr_accessor :solution_id
221
+ # @return [String] Which service triggers this script
222
+ attr_accessor :service
223
+ # @return [String] Which event triggers this script
224
+ attr_accessor :event
225
+ end
226
+
198
227
  def initialize
199
228
  super
200
229
  @uriparts << 'eventhandler'
@@ -204,18 +233,18 @@ module MrMurano
204
233
  end
205
234
 
206
235
  def mkalias(remote)
207
- if remote.has_key? :service and remote.has_key? :event then
208
- [$cfg['solution.id'], remote[:service], remote[:event]].join('_')
236
+ if remote.service.nil? or remote.event.nil? then
237
+ raise "Missing parts! #{remote.to_h.to_json}"
209
238
  else
210
- raise "Missing parts! #{remote.to_json}"
239
+ [$cfg['solution.id'], remote[:service], remote[:event]].join('_')
211
240
  end
212
241
  end
213
242
 
214
243
  def mkname(remote)
215
- if remote.has_key? :service and remote.has_key? :event then
216
- [remote[:service], remote[:event]].join('_')
244
+ if remote.service.nil? or remote.event.nil? then
245
+ raise "Missing parts! #{remote.to_h.to_json}"
217
246
  else
218
- raise "Missing parts! #{remote.to_json}"
247
+ [remote[:service], remote[:event]].join('_')
219
248
  end
220
249
  end
221
250
 
@@ -229,7 +258,7 @@ module MrMurano
229
258
  ( skiplist.include? i[:service] or
230
259
  skiplist.include? "#{i[:service]}.#{i[:event]}"
231
260
  )
232
- }
261
+ }.map{|i| EventHandlerItem.new(i)}
233
262
  end
234
263
 
235
264
  def fetch(name)
@@ -266,11 +295,11 @@ module MrMurano
266
295
  md = @match_header.match(line)
267
296
  if not md.nil? then
268
297
  # header line.
269
- cur = {:service=>md[:service],
270
- :event=>md[:event],
271
- :local_path=>path,
272
- :line=>lineno,
273
- :script=>line}
298
+ cur = EventHandlerItem.new(:service=>md[:service],
299
+ :event=>md[:event],
300
+ :local_path=>path,
301
+ :line=>lineno,
302
+ :script=>line)
274
303
  elsif not cur.nil? and not cur[:script].nil? then
275
304
  cur[:script] << line
276
305
  end
@@ -287,12 +316,13 @@ module MrMurano
287
316
  unless service.nil? or event.nil? then
288
317
  warning "Event in #{spath} missing header, but has legacy support."
289
318
  warning "Please add the header \"--#EVENT #{service} #{event}\""
290
- cur = {:service=>service,
291
- :event=>event,
292
- :local_path=>path,
293
- :line=>0,
294
- :line_end => lineno,
295
- :script=>path.read()} # FIXME: ick, fix this.
319
+ cur = EventHandlerItem.new(:service=>service,
320
+ :event=>event,
321
+ :local_path=>path,
322
+ :line=>0,
323
+ :line_end => lineno,
324
+ :script=>path.read() # FIXME: ick, fix this.
325
+ )
296
326
  end
297
327
  end
298
328
  cur
@@ -9,18 +9,19 @@ require 'MrMurano/hash'
9
9
  module MrMurano
10
10
  ## Track what things are syncable.
11
11
  class SyncRoot
12
+ # A thing that is syncable.
12
13
  Syncable = Struct.new(:name, :class, :type, :desc, :bydefault) do
13
14
  end
14
15
 
15
16
  ##
16
17
  # Add a new entry to syncable things
17
- # +name+:: The name to use for the long option
18
- # +klass+:: The class to instanciate from
19
- # +type+:: Single letter for short option and status listing
20
- # +desc+:: Summary of what this syncs.
21
- # +bydefault+:: Is this part of the default sync group
18
+ # @param name [String] The name to use for the long option
19
+ # @param klass [Class] The class to instanciate from
20
+ # @param type [String] Single letter for short option and status listing
21
+ # @param desc [String] Summary of what this syncs.
22
+ # @param bydefault [Boolean] Is this part of the default sync group
22
23
  #
23
- # returns nil
24
+ # @return [nil]
24
25
  def self.add(name, klass, type, desc, bydefault=false)
25
26
  @@syncset = [] unless defined?(@@syncset)
26
27
  @@syncset << Syncable.new(name.to_s, klass, type, desc, bydefault)
@@ -35,29 +36,29 @@ module MrMurano
35
36
 
36
37
  ##
37
38
  # Get the list of default syncables.
38
- # returns array of names
39
+ # @return [Array<String>] array of names
39
40
  def self.bydefault
40
41
  @@syncset.select{|a| a.bydefault }.map{|a| a.name}
41
42
  end
42
43
 
43
44
  ##
44
45
  # Iterate over all syncables
45
- # +block+:: code to run on each
46
+ # @param block code to run on each
46
47
  def self.each(&block)
47
48
  @@syncset.each{|a| yield a.name, a.type, a.class }
48
49
  end
49
50
 
50
51
  ##
51
52
  # Iterate over all syncables with option arguments.
52
- # +block+:: code to run on each
53
+ # @param block code to run on each
53
54
  def self.each_option(&block)
54
55
  @@syncset.each{|a| yield "-#{a.type.downcase}", "--[no-]#{a.name}", a.desc}
55
56
  end
56
57
 
57
58
  ##
58
59
  # Iterate over just the selected syncables.
59
- # +opt+:: Options hash of which to select from
60
- # +block+:: code to run on each
60
+ # @param opt [Hash{Symbol=>Boolean}] Options hash of which to select from
61
+ # @param block code to run on each
61
62
  def self.each_filtered(opt, &block)
62
63
  self.checkSAME(opt)
63
64
  @@syncset.each do |a|
@@ -70,9 +71,9 @@ module MrMurano
70
71
  ## Adjust options based on all or none
71
72
  # If none are selected, select the bydefault ones.
72
73
  #
73
- # +opt+:: Options hash of which to select from
74
+ # @param opt [Hash{Symbol=>Boolean}] Options hash of which to select from
74
75
  #
75
- # returns nil
76
+ # @return [nil]
76
77
  def self.checkSAME(opt)
77
78
  if opt[:all] then
78
79
  @@syncset.each {|a| opt[a.name.to_sym] = true }
@@ -88,7 +89,139 @@ module MrMurano
88
89
  end
89
90
  end
90
91
 
92
+ ## The functionality of a Syncable thing.
93
+ #
94
+ # This provides the logic for computing what things have changed, and pushing and
95
+ # pulling those things.
96
+ #
91
97
  module SyncUpDown
98
+
99
+ # This is one item that can be synced
100
+ class Item
101
+ # @return [String] The name of this item
102
+ attr_accessor :name
103
+ # @return [Pathname] Where this item lives
104
+ attr_accessor :local_path
105
+ # ??? what is this?
106
+ attr_accessor :id
107
+ # @return [String] The lua code for this item. (not all items use this.)
108
+ attr_accessor :script
109
+ # @return [Integer] The line in #local_path where this #script starts
110
+ attr_accessor :line
111
+ # @return [Integer] The line in #local_path where this #script ends
112
+ attr_accessor :line_end
113
+ # @return [String] If requested, the diff output
114
+ attr_accessor :diff
115
+ # @return [Boolean] When filtering, did this item pass.
116
+ attr_accessor :selected
117
+ # ???? what is this?
118
+ attr_accessor :synckey
119
+
120
+ # Initialize a new Item with a few, or all, attributes.
121
+ # @param hsh [Hash{Symbol=>Object}, Item] Initial values
122
+ #
123
+ # @example Initializing with a Hash
124
+ # Item.new(:name=>'Bob', :local_path => Pathname.new(…))
125
+ # @example Initializing with an Item
126
+ # item = Item.new(:name => 'get')
127
+ # Item.new(item)
128
+ def initialize(hsh={})
129
+ hsh.each_pair{|k,v| self[k] = v}
130
+ end
131
+
132
+ def as_inst(key)
133
+ return key if key.to_s[0] == '@'
134
+ return "@#{key}"
135
+ end
136
+ private :as_inst
137
+ def as_sym(key)
138
+ return key.to_sym if key.to_s[0] != '@'
139
+ return key.to_s[1..-1].to_sym
140
+ end
141
+ private :as_sym
142
+
143
+ # Get attribute as if this was a Hash
144
+ # @param key [String,Symbol] attribute name
145
+ # @return [Object] The value
146
+ def [](key)
147
+ public_send(key.to_sym)
148
+ end
149
+
150
+ # Set attribute as if this was a Hash
151
+ # @param key [String,Symbol] attribute name
152
+ # @param value [Object] value to set
153
+ def []=(key,value)
154
+ public_send("#{key}=", value)
155
+ end
156
+
157
+ # Delete a key
158
+ # @param key [String,Symbol] attribute name
159
+ # @return [Object] The value
160
+ def delete(key)
161
+ inst = as_inst(key)
162
+ remove_instance_variable(inst) if instance_variable_defined?(inst)
163
+ end
164
+
165
+ # @return [Hash{Symbol=>Object}] A hash that represents this Item
166
+ def to_h
167
+ Hash[ instance_variables.map{|k| [ as_sym(k), instance_variable_get(k)]} ]
168
+ end
169
+
170
+ # Adds the contents of item to self.
171
+ # @param item [Item,Hash] Stuff to merge
172
+ # @return [Item] ourself
173
+ def merge!(item)
174
+ item.each_pair{|k,v| self[k] = v}
175
+ self
176
+ end
177
+
178
+ # A new Item containing our plus items.
179
+ # @param item [Item,Hash] Stuff to merge
180
+ # @return [Item] New item with contents of both
181
+ def merge(item)
182
+ dup.merge!(item)
183
+ end
184
+
185
+ # Calls block once for each non-nil key
186
+ # @yieldparam key [Symbol] The name of the key
187
+ # @yieldparam value [Object] The value for that key
188
+ # @return [Item]
189
+ def each_pair(&block)
190
+ instance_variables.each do |key|
191
+ yield as_sym(key), instance_variable_get(key)
192
+ end
193
+ self
194
+ end
195
+
196
+ # Delete items in self that block returns true.
197
+ # @yieldparam key [Symbol] The name of the key
198
+ # @yieldparam value [Object] The value for that key
199
+ # @yieldreturn [Boolean] True to delete this key
200
+ # @return [Item] Ourself.
201
+ def reject!(&block)
202
+ instance_variables.each do |key|
203
+ drop = yield as_sym(key), instance_variable_get(key)
204
+ delete(key) if drop
205
+ end
206
+ self
207
+ end
208
+
209
+ # A new Item with keys deleted where block is true
210
+ # @yieldparam key [Symbol] The name of the key
211
+ # @yieldparam value [Object] The value for that key
212
+ # @yieldreturn [Boolean] True to delete this key
213
+ # @return [Item] New Item with keys deleted
214
+ def reject(&block)
215
+ dup.reject!(&block)
216
+ end
217
+
218
+ # For unit testing.
219
+ include Comparable
220
+ def <=>(anOther)
221
+ self.to_h <=> anOther.to_h
222
+ end
223
+ end
224
+
92
225
  #######################################################################
93
226
  # Methods that must be overridden
94
227
 
@@ -97,7 +230,7 @@ module MrMurano
97
230
  #
98
231
  # Children objects Must override this
99
232
  #
100
- # @return Array: of Hashes of item details
233
+ # @return [Array] of Hashes of item details
101
234
  def list()
102
235
  []
103
236
  end
@@ -106,7 +239,7 @@ module MrMurano
106
239
  #
107
240
  # Children objects Must override this
108
241
  #
109
- # @param itemkey String: The identifying key for this item
242
+ # @param itemkey [String] The identifying key for this item
110
243
  def remove(itemkey)
111
244
  # :nocov:
112
245
  raise "Forgotten implementation"
@@ -117,9 +250,9 @@ module MrMurano
117
250
  #
118
251
  # Children objects Must override this
119
252
  #
120
- # @param src Pathname: Full path of where to upload from
121
- # @param item Hash: The item details to upload
122
- # @param modify Bool: True if item exists already and this is changing it
253
+ # @param src [Pathname] Full path of where to upload from
254
+ # @param item [Hash] The item details to upload
255
+ # @param modify [Bool] True if item exists already and this is changing it
123
256
  def upload(src, item, modify)
124
257
  # :nocov:
125
258
  raise "Forgotten implementation"
@@ -148,14 +281,14 @@ module MrMurano
148
281
  #
149
282
  # @param root [Pathname,String] Root path for this resource type from config files
150
283
  # @param path [Pathname,String] Path to local item
151
- # @return [Hash] hash of the details for the remote item for this path
284
+ # @return [Item] hash of the details for the remote item for this path
152
285
  def toRemoteItem(root, path)
153
286
  # This mess brought to you by Windows short path names.
154
287
  path = Dir.glob(path.to_s).first
155
288
  root = Dir.glob(root.to_s).first
156
289
  path = Pathname.new(path)
157
290
  root = Pathname.new(root)
158
- {:name => path.realpath.relative_path_from(root.realpath).to_s}
291
+ Item.new(:name => path.realpath.relative_path_from(root.realpath).to_s)
159
292
  end
160
293
 
161
294
  ##
@@ -163,8 +296,8 @@ module MrMurano
163
296
  #
164
297
  # Children objects should override this or #tolocalpath
165
298
  #
166
- # @param item Hash: listing details for the item.
167
- # @param itemkey Symbol: Key for look up.
299
+ # @param item [Item] listing details for the item.
300
+ # @param itemkey [Symbol] Key for look up.
168
301
  def tolocalname(item, itemkey)
169
302
  item[itemkey].to_s
170
303
  end
@@ -177,11 +310,11 @@ module MrMurano
177
310
  #
178
311
  # Children objects should override this or #tolocalname
179
312
  #
180
- # @param into Pathname: Root path for this resource type from config files
181
- # @param item Hash: listing details for the item.
182
- # @return Pathname: path to save (or merge) remote item into
313
+ # @param into [Pathname] Root path for this resource type from config files
314
+ # @param item [Item] listing details for the item.
315
+ # @return [Pathname] path to save (or merge) remote item into
183
316
  def tolocalpath(into, item)
184
- return item[:local_path] if item.has_key? :local_path
317
+ return item[:local_path] unless item.local_path.nil?
185
318
  itemkey = @itemkey.to_sym
186
319
  name = tolocalname(item, itemkey)
187
320
  raise "Bad key(#{itemkey}) for #{item}" if name.nil?
@@ -196,7 +329,9 @@ module MrMurano
196
329
  #
197
330
  # Check child specific patterns against item
198
331
  #
199
- # @returns true or false
332
+ # @param item [Item] Item to be checked
333
+ # @param pattern [String] pattern to check with
334
+ # @return [Bool] true or false
200
335
  def match(item, pattern)
201
336
  false
202
337
  end
@@ -205,8 +340,8 @@ module MrMurano
205
340
  #
206
341
  # Children objects should override this if synckey is not @itemkey
207
342
  #
208
- # @param item Hash: The item to get a key from
209
- # @returns Object: The object to use a comparison key
343
+ # @param item [Item] The item to get a key from
344
+ # @return [Object] The object to use a comparison key
210
345
  def synckey(item)
211
346
  key = @itemkey.to_sym
212
347
  item[key]
@@ -216,13 +351,13 @@ module MrMurano
216
351
  #
217
352
  # Children objects should override this or implement #fetch()
218
353
  #
219
- # @param local Pathname: Full path of where to download to
220
- # @param item Hash: The item to download
354
+ # @param local [Pathname] Full path of where to download to
355
+ # @param item [Item] The item to download
221
356
  def download(local, item)
222
- if item[:bundled] then
223
- warning "Not downloading into bundled item #{synckey(item)}"
224
- return
225
- end
357
+ # if item[:bundled] then
358
+ # warning "Not downloading into bundled item #{synckey(item)}"
359
+ # return
360
+ # end
226
361
  local.dirname.mkpath
227
362
  id = item[@itemkey.to_sym]
228
363
  if id.nil? then
@@ -243,8 +378,8 @@ module MrMurano
243
378
  # Children objects should override this if move than just unlinking the local
244
379
  # item.
245
380
  #
246
- # @param dest Pathname: Full path of item to be removed
247
- # @param item Hash: Full details of item to be removed
381
+ # @param dest [Pathname] Full path of item to be removed
382
+ # @param item [Item] Full details of item to be removed
248
383
  def removelocal(dest, item)
249
384
  dest.unlink
250
385
  end
@@ -253,8 +388,7 @@ module MrMurano
253
388
  #######################################################################
254
389
 
255
390
 
256
- ##
257
- # So, for bundles this needs to look at all the places and build up the mered
391
+ # So, for bundles this needs to look at all the places and build up the merged
258
392
  # stack of local items.
259
393
  #
260
394
  # Which means it needs the from to be split into the base and the sub so we can
@@ -267,7 +401,7 @@ module MrMurano
267
401
  # #localitems
268
402
  #
269
403
  # This collects items in the project and all bundles.
270
- # @return Array: of Hashes of items
404
+ # @return [Array<Item>] items found
271
405
  def locallist()
272
406
  # so. if @locationbase/bundles exists
273
407
  # gather and merge: @locationbase/bundles/*/@location
@@ -303,6 +437,7 @@ module MrMurano
303
437
 
304
438
  ##
305
439
  # Get the full path for the local versions
440
+ # @return [Pathname] Location for local items
306
441
  def location
307
442
  raise "Missing @project_section" if @project_section.nil?
308
443
  Pathname.new($cfg['location.base']) + $project["#{@project_section}.location"]
@@ -310,12 +445,14 @@ module MrMurano
310
445
 
311
446
  ##
312
447
  # Returns array of globs to search for files
448
+ # @return [Array<String>] of Strings that are globs
313
449
  def searchFor
314
450
  raise "Missing @project_section" if @project_section.nil?
315
451
  $project["#{@project_section}.include"]
316
452
  end
317
453
 
318
454
  ## Returns array of globs of files to ignore
455
+ # @return [Array<String>] of Strings that are globs
319
456
  def ignoring
320
457
  raise "Missing @project_section" if @project_section.nil?
321
458
  $project["#{@project_section}.exclude"]
@@ -327,8 +464,8 @@ module MrMurano
327
464
  # Children rarely need to override this. Only when the locallist is not a set
328
465
  # of files in a directory will they need to override it.
329
466
  #
330
- # @param from Pathname: Directory of items to scan
331
- # @return Array: of Hashes of item details
467
+ # @param from [Pathname] Directory of items to scan
468
+ # @return [Array<Item>] Items found
332
469
  def localitems(from)
333
470
  # TODO: Profile this.
334
471
  debug "#{self.class.to_s}: Getting local items from: #{from}"
@@ -357,6 +494,8 @@ module MrMurano
357
494
  ##
358
495
  # Take a hash or something (a Commander::Command::Options) and return a hash
359
496
  #
497
+ # @param hsh [Hash, Commander::Command::Options] Thing we want to be a Hash
498
+ # @return [Hash] an actual Hash with default value of false
360
499
  def elevate_hash(hsh)
361
500
  # Commander::Command::Options stripped all of the methods from parent
362
501
  # objects. I have not nice thoughts about that.
@@ -374,6 +513,9 @@ module MrMurano
374
513
  #
375
514
  # This creates, uploads, and deletes things as needed up in Murano to match
376
515
  # what is in the local project directory.
516
+ #
517
+ # @param options [Hash, Commander::Command::Options] Options on opertation
518
+ # @param selected [Array<String>] Filters for _matcher
377
519
  def syncup(options={}, selected=[])
378
520
  options = elevate_hash(options)
379
521
  itemkey = @itemkey.to_sym
@@ -413,6 +555,9 @@ module MrMurano
413
555
  #
414
556
  # This creates, downloads, and deletes things as needed up in the local project
415
557
  # directory to match what is in Murano.
558
+ #
559
+ # @param options [Hash, Commander::Command::Options] Options on opertation
560
+ # @param selected [Array<String>] Filters for _matcher
416
561
  def syncdown(options={}, selected=[])
417
562
  options = elevate_hash(options)
418
563
  options[:asdown] = true
@@ -452,9 +597,11 @@ module MrMurano
452
597
  end
453
598
 
454
599
  ## Call external diff tool on item
600
+ #
455
601
  # WARNING: This will download the remote item to do the diff.
456
- # @param item Hash: The item to get a diff of
457
- # @return String: The diff output
602
+ #
603
+ # @param item [Item] The item to get a diff of
604
+ # @return [String] The diff output
458
605
  def dodiff(item)
459
606
  trmt = Tempfile.new([tolocalname(item, @itemkey)+'_remote_', '.lua'])
460
607
  tlcl = Tempfile.new([tolocalname(item, @itemkey)+'_local_', '.lua'])
@@ -487,6 +634,8 @@ module MrMurano
487
634
 
488
635
  ##
489
636
  # Check if an item matches a pattern.
637
+ # @param items [Array<Item>] Of items to filter
638
+ # @param patterns [Array<String>] Filters for _matcher
490
639
  def _matcher(items, patterns)
491
640
  items.map do |item|
492
641
  if patterns.empty? then
@@ -495,7 +644,7 @@ module MrMurano
495
644
  item[:selected] = patterns.any? do |pattern|
496
645
  if pattern.to_s[0] == '#' then
497
646
  match(item, pattern)
498
- elsif not item.has_key? :local_path then
647
+ elsif item.local_path.nil? then
499
648
  false
500
649
  else
501
650
  item[:local_path].fnmatch(pattern)
@@ -508,22 +657,24 @@ module MrMurano
508
657
  private :_matcher
509
658
 
510
659
  ## Get status of things here verses there
660
+ #
661
+ # @param options [Hash, Commander::Command::Options] Options on opertation
662
+ # @param selected [Array<String>] Filters for _matcher
663
+ # @return [Hash{Symbol=>Array<Item>}] Items grouped by the action that should be taken
511
664
  def status(options={}, selected=[])
512
665
  options = elevate_hash(options)
513
666
  itemkey = @itemkey.to_sym
514
667
 
515
- there = _matcher(list(), selected)
516
- here = _matcher(locallist(), selected)
668
+ there = _matcher(list(), selected) # Array<Item>
669
+ here = _matcher(locallist(), selected) # Array<Item>
517
670
 
518
671
  therebox = {}
519
672
  there.each do |item|
520
- item = Hash.transform_keys_to_symbols(item)
521
673
  item[:synckey] = synckey(item)
522
674
  therebox[ item[:synckey] ] = item
523
675
  end
524
676
  herebox = {}
525
677
  here.each do |item|
526
- item = Hash.transform_keys_to_symbols(item)
527
678
  item[:synckey] = synckey(item)
528
679
  herebox[ item[:synckey] ] = item
529
680
  end