MrMurano 1.6.3 → 1.7.0

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/Gemfile +1 -1
  4. data/MrMurano.gemspec +1 -1
  5. data/README.markdown +4 -0
  6. data/TODO.taskpaper +17 -4
  7. data/lib/MrMurano/Account.rb +5 -1
  8. data/lib/MrMurano/Config.rb +3 -1
  9. data/lib/MrMurano/Product-Resources.rb +239 -0
  10. data/lib/MrMurano/Product.rb +51 -2
  11. data/lib/MrMurano/Solution-Cors.rb +81 -0
  12. data/lib/MrMurano/Solution-Endpoint.rb +8 -4
  13. data/lib/MrMurano/Solution-File.rb +4 -2
  14. data/lib/MrMurano/Solution-ServiceConfig.rb +74 -1
  15. data/lib/MrMurano/Solution-Services.rb +4 -2
  16. data/lib/MrMurano/Solution-Users.rb +6 -3
  17. data/lib/MrMurano/Solution.rb +6 -274
  18. data/lib/MrMurano/SyncUpDown.rb +433 -0
  19. data/lib/MrMurano/commands/completion.rb +152 -0
  20. data/lib/MrMurano/commands/content.rb +15 -14
  21. data/lib/MrMurano/commands/cors.rb +11 -38
  22. data/lib/MrMurano/commands/exportImport.rb +4 -3
  23. data/lib/MrMurano/commands/keystore.rb +15 -16
  24. data/lib/MrMurano/commands/logs.rb +2 -2
  25. data/lib/MrMurano/commands/productCreate.rb +4 -4
  26. data/lib/MrMurano/commands/productDelete.rb +6 -8
  27. data/lib/MrMurano/commands/productSpec.rb +31 -36
  28. data/lib/MrMurano/commands/productWrite.rb +9 -7
  29. data/lib/MrMurano/commands/serialNumberCmds.rb +4 -4
  30. data/lib/MrMurano/commands/solutionCreate.rb +4 -4
  31. data/lib/MrMurano/commands/solutionDelete.rb +5 -5
  32. data/lib/MrMurano/commands/status.rb +9 -42
  33. data/lib/MrMurano/commands/sync.rb +15 -71
  34. data/lib/MrMurano/commands/timeseries.rb +23 -29
  35. data/lib/MrMurano/commands/tsdb.rb +202 -0
  36. data/lib/MrMurano/commands/zshcomplete.erb +112 -0
  37. data/lib/MrMurano/commands.rb +4 -1
  38. data/lib/MrMurano/http.rb +4 -3
  39. data/lib/MrMurano/makePretty.rb +15 -6
  40. data/lib/MrMurano/verbosing.rb +71 -0
  41. data/lib/MrMurano/version.rb +1 -1
  42. data/lib/MrMurano.rb +1 -0
  43. data/spec/ConfigFile_spec.rb +3 -3
  44. data/spec/ProductContent_spec.rb +2 -2
  45. data/spec/ProductResources_spec.rb +152 -0
  46. data/spec/Product_spec.rb +38 -1
  47. data/spec/Solution-Cors_spec.rb +134 -0
  48. data/spec/Solution-ServiceConfig_spec.rb +198 -0
  49. data/spec/SyncRoot_spec.rb +74 -0
  50. data/spec/cmd_config_spec.rb +51 -0
  51. data/spec/fixtures/.mrmuranorc +9 -0
  52. data/spec/{testfiles → fixtures}/configfile +0 -0
  53. data/spec/fixtures/mrmuranorc_deleted_bob +8 -0
  54. data/spec/fixtures/product_spec_files/example.exoline.spec.yaml +116 -0
  55. data/spec/fixtures/product_spec_files/example.murano.spec.yaml +14 -0
  56. data/spec/fixtures/product_spec_files/gwe.exoline.spec.yaml +21 -0
  57. data/spec/fixtures/product_spec_files/gwe.murano.spec.yaml +16 -0
  58. data/spec/{lightbulb.yaml → fixtures/product_spec_files/lightbulb.yaml} +0 -0
  59. data/spec/spec_helper.rb +4 -4
  60. metadata +47 -19
@@ -1,54 +1,27 @@
1
-
2
- module MrMurano
3
- class Cors < SolutionBase
4
- def initialize
5
- super
6
- @uriparts << 'cors'
7
- @location = $cfg['location.cors']
8
- end
9
-
10
- def fetch()
11
- ret = get()
12
- ret[:cors]
13
- end
14
-
15
- # TODO: fill out other metheds so this could be part of sync up/down.
16
-
17
- ##
18
- # Upload CORS
19
- # :local path to file to push
20
- # :remote hash of method and endpoint path (ignored for now)
21
- def upload(local, remote)
22
- local = Pathname.new(local) unless local.kind_of? Pathname
23
- raise "no file" unless local.exist?
24
-
25
- local.open do |io|
26
- data = YAML.load(io)
27
- put('', data)
28
- end
29
- end
30
-
31
- def tolocalpath(into, item)
32
- into
33
- end
34
- end
35
- end
1
+ require 'yaml'
2
+ require 'MrMurano/Solution-Cors'
36
3
 
37
4
  command :cors do |c|
38
5
  c.syntax = %{mr cors [options]}
39
- c.description = %{Get or set the CORS for the solution.}
6
+ c.summary = %{Get or set the CORS for the solution. [Deprecated]}
7
+ c.description = %{Get or set the CORS for the solution.
8
+
9
+ This is deprecated. Use `mr syncup --cors` or `mr syncdown --cors` instead.
10
+ }
40
11
  c.option '-f','--file FILE', String, %{File to set CORS from}
41
12
 
42
13
  c.action do |args,options|
14
+ say_warning "This is deprecated. Use `mr syncup --cors` or `mr syncdown --cors` instead."
43
15
  sol = MrMurano::Cors.new
44
16
 
45
17
  if options.file then
46
18
  #set
47
- pp sol.upload(options.file, {})
19
+ data = sol.localitems(options.file)
20
+ sol.outf sol.upload(options.file, data.first)
48
21
  else
49
22
  # get
50
23
  ret = sol.fetch()
51
- puts ret
24
+ sol.outf ret
52
25
  end
53
26
  end
54
27
 
@@ -8,7 +8,7 @@ command 'config export' do |c|
8
8
  c.description = %{Export data to Solutionfiles
9
9
 
10
10
  This will write to the Solutionfile.json and .Solutionfile.secret used by the
11
- exosite-cil tool.
11
+ exosite-cli tool.
12
12
 
13
13
  This also will merge all of the endpoints into a single 'routes.lua' file.
14
14
  }
@@ -23,8 +23,9 @@ command 'config export' do |c|
23
23
  solsecret = Pathname.new($cfg['location.base'] + '.Solutionfile.secret')
24
24
 
25
25
  if not options.force and (solfile.exist? or solsecret.exist?) then
26
- say_error "Solutionfile.json or .Solutionfile.secret already exist."
27
- say "Use --force to overwrite"
26
+ sol = MrMurano::Solution.new
27
+ sol.error "Solutionfile.json or .Solutionfile.secret already exist."
28
+ sol.error "Use --force to overwrite"
28
29
  end
29
30
 
30
31
  solf = {
@@ -1,3 +1,4 @@
1
+ require 'MrMurano/Solution-ServiceConfig'
1
2
 
2
3
  module MrMurano
3
4
  class Keystore < ServiceConfig
@@ -7,29 +8,29 @@ module MrMurano
7
8
  end
8
9
 
9
10
  def keyinfo
10
- ret = get("/#{scid}/call/info")
11
+ call(:info)
11
12
  end
12
13
 
13
14
  def listkeys
14
- ret = get("/#{scid}/call/list")
15
+ ret = call(:list)
15
16
  ret[:keys]
16
17
  end
17
18
 
18
19
  def getkey(key)
19
- ret = post("/#{scid}/call/get", {:key=>key})
20
+ ret = call(:get, :post, {:key=>key})
20
21
  ret[:value]
21
22
  end
22
23
 
23
24
  def setkey(key, value)
24
- post("/#{scid}/call/set", { :key=>key, :value=>value })
25
+ call(:set, :post, { :key=>key, :value=>value })
25
26
  end
26
27
 
27
28
  def delkey(key)
28
- post("/#{scid}/call/delete", { :key=>key})
29
+ call(:delete, { :key=>key})
29
30
  end
30
31
 
31
32
  def command(key, cmd, args)
32
- post("/#{scid}/call/command", {:key=>key, :command=>cmd, :args=>args})
33
+ call(:command, {:key=>key, :command=>cmd, :args=>args})
33
34
  end
34
35
 
35
36
  end
@@ -40,7 +41,7 @@ command 'keystore info' do |c|
40
41
  c.description = %{Show info about the Keystore}
41
42
  c.action do |args,options|
42
43
  sol = MrMurano::Keystore.new
43
- pp sol.keyinfo
44
+ sol.outf sol.keyinfo
44
45
  end
45
46
  end
46
47
 
@@ -49,9 +50,7 @@ command 'keystore list' do |c|
49
50
  c.description = %{List all of the keys in the Keystore}
50
51
  c.action do |args,options|
51
52
  sol = MrMurano::Keystore.new
52
- sol.listkeys.each do |key|
53
- puts key
54
- end
53
+ sol.outf sol.listkeys
55
54
  end
56
55
  end
57
56
  alias_command :keystore, 'keystore list'
@@ -62,7 +61,7 @@ command 'keystore get' do |c|
62
61
  c.action do |args,options|
63
62
  sol = MrMurano::Keystore.new
64
63
  ret = sol.getkey(args[0])
65
- puts ret
64
+ sol.outf ret
66
65
  end
67
66
  end
68
67
 
@@ -98,16 +97,16 @@ See http://docs.exosite.com/murano/services/keystore/#command for current list.
98
97
  c.example %{mr keystore command lpush mykey A B C}, %{Push three values onto list}
99
98
  c.example %{mr keystore command lrem mykey 0 B}, %{Remove all B values from list}
100
99
  c.action do |args,options|
100
+ sol = MrMurano::Keystore.new
101
101
  if args.count < 2 then
102
- say_error "Not enough params"
102
+ sol.error "Not enough params"
103
103
  else
104
- sol = MrMurano::Keystore.new
105
104
  ret = sol.command(args[1], args[0], args[2..-1])
106
105
  if ret.has_key?(:value) then
107
- puts ret[:value]
106
+ sol.outf ret[:value]
108
107
  else
109
- say_error "#{ret[:code]}: #{ret.message}"
110
- pp ret[:error] if ($cfg['tool.debug'] and ret.has_key?(:error))
108
+ sol.error "#{ret[:code]}: #{ret.message}"
109
+ sol.outf ret[:error] if ($cfg['tool.debug'] and ret.has_key?(:error))
111
110
  end
112
111
  end
113
112
  end
@@ -38,7 +38,7 @@ command :logs do |c|
38
38
  :create_additions=>false})
39
39
  puts MrMurano::Pretties::makePretty(js, options)
40
40
  rescue
41
- say_error '=== JSON parse error, showing raw instead ==='
41
+ sol.error '=== JSON parse error, showing raw instead ==='
42
42
  puts m
43
43
  end
44
44
  end
@@ -68,7 +68,7 @@ command :logs do |c|
68
68
  end
69
69
  end
70
70
  else
71
- say_error "Couldn't get logs: #{ret}"
71
+ sol.error "Couldn't get logs: #{ret}"
72
72
  break
73
73
  end
74
74
 
@@ -4,22 +4,22 @@ command 'product create' do |c|
4
4
  c.description = %{Create a new product}
5
5
 
6
6
  c.action do |args, options|
7
+ acc = MrMurano::Account.new
7
8
  if args.count < 1 then
8
- say_error "Name of product missing"
9
+ acc.error "Name of product missing"
9
10
  return
10
11
  end
11
12
  name = args[0]
12
13
 
13
- acc = MrMurano::Account.new
14
14
  ret = acc.new_product(name)
15
15
  if not ret.kind_of?(Hash) and not ret.empty? then
16
- say_error "Create failed: #{ret.to_s}"
16
+ acc.error "Create failed: #{ret.to_s}"
17
17
  return
18
18
  end
19
19
 
20
20
  # create doesn't return anything, so we need to go look for it.
21
21
  ret = acc.products.select{|i| i[:label] == name}
22
- say ret.first[:modelId]
22
+ acc.outf ret.first[:modelId]
23
23
 
24
24
  end
25
25
  end
@@ -6,28 +6,26 @@ command 'product delete' do |c|
6
6
  c.description = %{Delete a product}
7
7
 
8
8
  c.action do |args, options|
9
+ acc = MrMurano::Account.new
9
10
  if args.count < 1 then
10
- say_error "Product id or name missing"
11
+ acc.error "Product id or name missing"
11
12
  return
12
13
  end
13
14
  name = args[0]
14
15
 
15
- acc = MrMurano::Account.new
16
16
 
17
17
  # Need to convert what we got into the internal PID.
18
18
  ret = acc.products.select{|i| i.has_value? name }
19
19
 
20
- if $cfg['tool.debug'] then
21
- say "Matches found:"
22
- pp ret
23
- end
20
+ acc.debug "Matches found:"
21
+ acc.outf(ret) if $cfg['tool.debug']
24
22
 
25
23
  if ret.empty? then
26
- say_error "No product matching '#{name}' found. Nothing to delete."
24
+ acc.error "No product matching '#{name}' found. Nothing to delete."
27
25
  else
28
26
  ret = acc.delete_product(ret.first[:pid])
29
27
  if not ret.kind_of?(Hash) and not ret.empty? then
30
- say_error "Delete failed: #{ret.to_s}"
28
+ acc.error "Delete failed: #{ret.to_s}"
31
29
  end
32
30
  end
33
31
  end
@@ -1,6 +1,8 @@
1
+ require 'MrMurano/Account'
1
2
  require 'MrMurano/Product'
2
3
  require 'MrMurano/hash'
3
4
  require 'yaml'
5
+ require 'terminal-table'
4
6
 
5
7
  command 'product spec convert' do |c|
6
8
  c.syntax = %{mr product spec convert FILE}
@@ -8,38 +10,22 @@ command 'product spec convert' do |c|
8
10
  c.option '-o', '--output FILE', %{Download to file instead of STDOUT}
9
11
 
10
12
  c.action do |args, options|
13
+ prd = MrMurano::Product.new
11
14
  if args.count == 0 then
12
- say_error "Missing file"
15
+ prd.error "Missing file"
13
16
  else
14
-
15
- File.open(args[0]) do |fin|
16
- spec = YAML.load(fin)
17
- unless spec.has_key?('dataports') then
18
- say_error "Not an exoline spec file"
19
- else
20
- dps = spec['dataports'].map do |dp|
21
- dp.delete_if{|k,v| k != 'alias' and k != 'format' and k != 'initial'}
22
- dp['format'] = 'string' if dp['format'][0..5] == 'string'
23
- dp
24
- end
25
-
26
- spec = {'resource'=>dps}
27
- if options.output then
28
- File.open(options.output, 'w') do |io|
29
- io << spec.to_yaml
30
- end
31
- else
32
- puts spec.to_yaml
33
- end
34
- end
35
- end
17
+ prd.outf prd.convert(args[0])
36
18
  end
37
19
  end
38
20
  end
39
21
 
40
22
  command 'product spec push' do |c|
41
23
  c.syntax = %{mr product spec push [--file FILE]}
42
- c.summary = %{Upload a new specification for a product}
24
+ c.summary = %{Upload a new specification for a product [Deprecated]}
25
+ c.description = %{Convert exoline spec file into Murano format
26
+
27
+ This is deprecated. Use `mr syncup --specs` instead.
28
+ }
43
29
 
44
30
  c.option '--file FILE', "The spec file to upload"
45
31
 
@@ -49,6 +35,8 @@ command 'product spec push' do |c|
49
35
  # - $cfg['product.spec']
50
36
 
51
37
  c.action do |args, options|
38
+ prd = MrMurano::Product.new
39
+ prd.warning "This is deprecated. Use `mr syncup --specs` instead."
52
40
 
53
41
  file = $cfg['product.spec']
54
42
  prid = $cfg['product.id']
@@ -56,10 +44,9 @@ command 'product spec push' do |c|
56
44
  file = options.file unless options.file.nil?
57
45
 
58
46
  if not file.nil? and FileTest.exist?(file) then
59
- prd = MrMurano::Product.new
60
- pp prd.update(file)
47
+ prd.outf prd.update(file)
61
48
  else
62
- say_error "No spec file to push: #{file}"
49
+ prd.error "No spec file to push: #{file}"
63
50
  end
64
51
  end
65
52
  end
@@ -69,27 +56,35 @@ command 'product spec pull' do |c|
69
56
  c.summary = %{Pull down the specification for a product}
70
57
 
71
58
  c.option '-o', '--output FILE', %{Download to file instead of STDOUT}
59
+ c.option '--aliasonly', 'Only return the aliases'
72
60
 
73
61
  c.action do |args, options|
74
62
  prd = MrMurano::Product.new
75
63
  ret = prd.info
76
64
 
77
- resources = ret[:resources].map do |r|
78
- r.delete(:rid)
79
- Hash.transform_keys_to_strings(r)
65
+ io=nil
66
+ if options.output then
67
+ io = File.open(options.output, 'w')
80
68
  end
81
69
 
82
- spec = { 'resources'=> resources }
70
+ if options.aliasonly then
71
+ ret = ret[:resources].map{|row| row[:alias]}
72
+ end
83
73
 
84
- if options.output then
85
- File.open(options.output, 'w') do |io|
86
- io << spec.to_yaml
74
+ prd.outf(ret, io) do |dd, ios|
75
+ if ret.kind_of? Array then
76
+ ios.puts ret.join(' ')
77
+ else
78
+ prd.tabularize({
79
+ :rows => ret[:resources].map{|r| [r[:alias], r[:format], r[:rid]]},
80
+ :headers => ['Alias', 'Format', 'RID']
81
+ }, ios)
87
82
  end
88
- else
89
- puts spec.to_yaml
90
83
  end
84
+ io.close unless io.nil?
91
85
  end
92
86
  end
93
87
  alias_command 'product spec', 'product spec pull'
88
+ alias_command 'product spec list', 'product spec pull', '--astable'
94
89
 
95
90
  # vim: set ai et sw=2 ts=2 :
@@ -6,17 +6,19 @@ command 'product write' do |c|
6
6
 
7
7
  c.action do |args,options|
8
8
  sn = args.shift
9
+ prd = MrMurano::Product.new
9
10
  if (args.count % 2) != 0 then
10
- say_error "Last alias is missing a value to write."
11
+ prd.error "Last alias is missing a value to write."
11
12
  else
12
13
  data = Hash[*args]
13
- prd = MrMurano::Product.new
14
14
  ret = prd.write(sn, data)
15
- ret.each_pair do |k,v|
16
- if v == 'ok' then
17
- say "#{k.to_s}: #{v}"
18
- else
19
- say_error "#{k.to_s}: #{v}"
15
+ prd.outf(ret) do |dd|
16
+ ret.each_pair do |k,v|
17
+ if v == 'ok' then
18
+ say "#{k.to_s}: #{v}"
19
+ else
20
+ prd.error "#{k.to_s}: #{v}"
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -42,7 +42,7 @@ the activation call within this time, it will need to be enabled again.
42
42
  elsif args.count > 0 then
43
43
  prd.enable(args[0])
44
44
  else
45
- say_error "Missing a serial number to enable"
45
+ prd.error "Missing a serial number to enable"
46
46
  end
47
47
  end
48
48
  end
@@ -61,14 +61,14 @@ CIK again.
61
61
  }
62
62
 
63
63
  c.action do |args,options|
64
+ prd = MrMurano::ProductSerialNumber.new
64
65
  if args.count < 1 then
65
- say_error "Serial number missing"
66
+ prd.error "Serial number missing"
66
67
  return
67
68
  end
68
69
  sn = args.first
69
70
 
70
- prd = MrMurano::ProductSerialNumber.new
71
- pp prd.activate(sn)
71
+ prd.outf prd.activate(sn)
72
72
 
73
73
  end
74
74
  end
@@ -4,22 +4,22 @@ command 'solution create' do |c|
4
4
  c.description = %{Create a new solution}
5
5
 
6
6
  c.action do |args, options|
7
+ acc = MrMurano::Account.new
7
8
  if args.count < 1 then
8
- say_error "Name of solution missing"
9
+ acc.error "Name of solution missing"
9
10
  return
10
11
  end
11
12
  name = args[0]
12
13
 
13
- acc = MrMurano::Account.new
14
14
  ret = acc.new_solution(name)
15
15
  if not ret.kind_of?(Hash) and not ret.empty? then
16
- say_error "Create failed: #{ret.to_s}"
16
+ acc.error "Create failed: #{ret.to_s}"
17
17
  return
18
18
  end
19
19
 
20
20
  # create doesn't return anything, so we need to go look for it.
21
21
  ret = acc.solutions.select{|i| i[:domain] =~ /#{name}\./}
22
- say ret.first[:apiId]
22
+ acc.outf ret.first[:apiId]
23
23
 
24
24
  end
25
25
  end
@@ -5,28 +5,28 @@ command 'solution delete' do |c|
5
5
  c.description = %{Delete a solution}
6
6
 
7
7
  c.action do |args, options|
8
+ acc = MrMurano::Account.new
8
9
  if args.count < 1 then
9
- say_error "Solution id or name missing"
10
+ acc.error "Solution id or name missing"
10
11
  return
11
12
  end
12
13
  name = args[0]
13
14
 
14
- acc = MrMurano::Account.new
15
15
 
16
16
  # Need to convert what we got into the internal PID.
17
17
  ret = acc.solutions.select{|i| i.has_value?(name) or i[:domain] =~ /#{name}\./ }
18
18
 
19
19
  if $cfg['tool.debug'] then
20
20
  say "Matches found:"
21
- pp ret
21
+ acc.outf ret
22
22
  end
23
23
 
24
24
  if ret.empty? then
25
- say_error "No solution matching '#{name}' found. Nothing to delete."
25
+ acc.error "No solution matching '#{name}' found. Nothing to delete."
26
26
  else
27
27
  ret = acc.delete_solution(ret.first[:sid])
28
28
  if not ret.kind_of?(Hash) and not ret.empty? then
29
- say_error "Delete failed: #{ret.to_s}"
29
+ acc.error "Delete failed: #{ret.to_s}"
30
30
  end
31
31
  end
32
32
  end
@@ -3,24 +3,21 @@ command :status do |c|
3
3
  c.syntax = %{mr status [options]}
4
4
  c.description = %{Get the status of files}
5
5
  c.option '--all', 'Check everything'
6
- c.option '-s','--[no-]files', %{Static Files}
7
- c.option '-a','--[no-]endpoints', %{Endpoints}
8
- c.option '-m','--[no-]modules', %{Modules}
9
- c.option '-e','--[no-]eventhandlers', %{Event Handlers}
10
- c.option '--[no-]roles', %{Roles}
11
- c.option '--[no-]users', %{Users}
6
+
7
+ # Load options to control which things to status
8
+ MrMurano::SyncRoot.each_option do |s,l,d|
9
+ c.option s, l, d
10
+ end
12
11
 
13
12
  c.option '--[no-]asdown', %{Report as if syncdown instead of syncup}
14
13
  c.option '--[no-]diff', %{For modified items, show a diff}
15
14
  c.option '--[no-]grouped', %{Group all adds, deletes, and mods together}
16
15
  c.option '--[no-]showall', %{List unchanged as well}
17
-
16
+
18
17
  c.action do |args,options|
19
18
  options.default :delete=>true, :create=>true, :update=>true, :diff=>false,
20
19
  :grouped => true
21
20
 
22
- MrMurano.checkSAME(options)
23
-
24
21
  def fmtr(item)
25
22
  if item.has_key? :local_path then
26
23
  item[:local_path].relative_path_from(Pathname.pwd()).to_s
@@ -54,41 +51,11 @@ command :status do |c|
54
51
  pretty(ret, options)
55
52
  end
56
53
  end
57
-
58
- if options.endpoints then
59
- sol = MrMurano::Endpoint.new
60
- ret = sol.status(options)
61
- gmerge(ret, 'A', options)
62
- end
63
-
64
- if options.modules then
65
- sol = MrMurano::Library.new
66
- ret = sol.status(options)
67
- gmerge(ret, 'M', options)
68
- end
69
-
70
- if options.eventhandlers then
71
- sol = MrMurano::EventHandler.new
72
- ret = sol.status(options)
73
- gmerge(ret, 'E', options)
74
- end
75
-
76
- if options.roles then
77
- sol = MrMurano::Role.new
78
- ret = sol.status(options)
79
- gmerge(ret, 'R', options)
80
- end
81
-
82
- if options.users then
83
- sol = MrMurano::User.new
84
- ret = sol.status(options)
85
- gmerge(ret, 'U', options)
86
- end
87
54
 
88
- if options.files then
89
- sol = MrMurano::File.new
55
+ MrMurano::SyncRoot.each_filtered(options.__hash__) do |name, type, klass|
56
+ sol = klass.new
90
57
  ret = sol.status(options)
91
- gmerge(ret, 'S', options)
58
+ gmerge(ret, type, options)
92
59
  end
93
60
 
94
61
  pretty(@grouped, options) if options.grouped