opennebula-cli 5.8.5 → 5.9.80.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,10 +20,16 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
- REMOTES_LOCATION = '/var/lib/one/remotes/'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
24
+ REMOTES_LOCATION = '/var/lib/one/remotes/'
24
25
  else
25
26
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
- REMOTES_LOCATION = ONE_LOCATION + '/var/remotes/'
27
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
28
+ REMOTES_LOCATION = ONE_LOCATION + '/var/remotes/'
29
+ end
30
+
31
+ if File.directory?(GEMS_LOCATION)
32
+ Gem.use_paths(GEMS_LOCATION)
27
33
  end
28
34
 
29
35
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -230,7 +236,7 @@ CommandParser::CmdParser.new(ARGV) do
230
236
  EOT
231
237
 
232
238
  command :show, show_desc, :hostid,
233
- :options => OpenNebulaHelper::XML do
239
+ :options => [OpenNebulaHelper::XML, OpenNebulaHelper::DECRYPT] do
234
240
  helper.show_resource(args[0], options)
235
241
  end
236
242
 
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -432,4 +438,14 @@ CommandParser::CmdParser.new(ARGV) do
432
438
  i.unlock
433
439
  end
434
440
  end
441
+
442
+ show_desc = <<-EOT.unindent
443
+ Shows orphans images (i.e images not referenced in any template).
444
+ EOT
445
+
446
+ command :orphans, show_desc do
447
+ puts helper.check_orphans
448
+
449
+ return 0
450
+ end
435
451
  end
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,12 +20,18 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  VAR_LOCATION = '/var/lib/one'
24
25
  else
25
26
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
27
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
26
28
  VAR_LOCATION = ONE_LOCATION + '/var'
27
29
  end
28
30
 
31
+ if File.directory?(GEMS_LOCATION)
32
+ Gem.use_paths(GEMS_LOCATION)
33
+ end
34
+
29
35
  $LOAD_PATH << RUBY_LIB_LOCATION
30
36
  $LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
31
37
 
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -72,11 +78,10 @@ CommandParser::CmdParser.new(ARGV) do
72
78
  :description => 'Read password from file'
73
79
  }
74
80
 
75
- SHA1 = {
76
- :name => 'sha1',
77
- :large => '--sha1',
78
- :description => "The password will be hashed using the sha1\n" \
79
- ' ' * 31 << 'algorithm'
81
+ SHA256 = {
82
+ :name => 'sha256',
83
+ :large => '--sha256',
84
+ :description => 'The password will be hashed using the sha256 algorithm'
80
85
  }
81
86
 
82
87
  SSH = {
@@ -203,7 +208,7 @@ CommandParser::CmdParser.new(ARGV) do
203
208
  :description => 'enable stdin password'
204
209
  }
205
210
 
206
- auth_options = [READ_FILE, SHA1, SSH, X509, KEY, CERT, DRIVER]
211
+ auth_options = [READ_FILE, SHA256, SSH, X509, KEY, CERT, DRIVER]
207
212
 
208
213
  create_options = auth_options.clone.unshift(GROUP_CREATE)
209
214
 
@@ -20,10 +20,16 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
- REMOTES_LOCATION = '/var/lib/one/remotes/'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
24
+ REMOTES_LOCATION = '/var/lib/one/remotes/'
24
25
  else
25
26
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
- REMOTES_LOCATION = ONE_LOCATION + '/var/remotes/'
27
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
28
+ REMOTES_LOCATION = ONE_LOCATION + '/var/remotes/'
29
+ end
30
+
31
+ if File.directory?(GEMS_LOCATION)
32
+ Gem.use_paths(GEMS_LOCATION)
27
33
  end
28
34
 
29
35
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -97,6 +103,14 @@ CommandParser::CmdParser.new(ARGV) do
97
103
  :format => String
98
104
  }
99
105
 
106
+ PORT = {
107
+ :name => 'port',
108
+ :short => '-p port',
109
+ :large => '--port port',
110
+ :format => String,
111
+ :description => 'vCenter API port, defaults to 443 (SSL) or 80'
112
+ }
113
+
100
114
  USE_DEFAULTS = {
101
115
  :name => 'defaults',
102
116
  :large => '--use-defaults',
@@ -234,7 +248,7 @@ CommandParser::CmdParser.new(ARGV) do
234
248
  EOT
235
249
  command :hosts,
236
250
  host_desc,
237
- :options => [VCENTER, USER, PASS, USE_DEFAULTS] do
251
+ :options => [VCENTER, USER, PASS, USE_DEFAULTS, PORT] do
238
252
  con_ops = helper.connection_options('Hosts', options)
239
253
 
240
254
  VCenterDriver::VcImporter.import_clusters(con_ops, options)
data/bin/onevdc CHANGED
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
data/bin/onevm CHANGED
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -220,6 +226,10 @@ CommandParser::CmdParser.new(ARGV) do
220
226
  helper.retrieve_snapshot_id(@current_vm, arg)
221
227
  end
222
228
 
229
+ format :disk_snapshot_id, 'Disk_snapshot identifier' do |arg|
230
+ helper.retrieve_disk_snapshot_id(@current_vm, arg)
231
+ end
232
+
223
233
  ########################################################################
224
234
  # Commands
225
235
  ########################################################################
@@ -869,7 +879,7 @@ CommandParser::CmdParser.new(ARGV) do
869
879
  resched_desc = <<-EOT.unindent
870
880
  Sets the rescheduling flag for the VM.
871
881
 
872
- States: RUNNING
882
+ States: RUNNING, POWEROFF
873
883
  EOT
874
884
 
875
885
  command :resched, resched_desc, [:range, :vmid_list] do
@@ -881,7 +891,7 @@ CommandParser::CmdParser.new(ARGV) do
881
891
  unresched_desc = <<-EOT.unindent
882
892
  Clears the rescheduling flag for the VM.
883
893
 
884
- States: RUNNING
894
+ States: RUNNING, POWEROFF
885
895
  EOT
886
896
 
887
897
  command :unresched, unresched_desc, [:range, :vmid_list] do
@@ -1045,8 +1055,9 @@ CommandParser::CmdParser.new(ARGV) do
1045
1055
  table = helper.format_pool(options)
1046
1056
  pool = OpenNebula::VirtualMachinePool.new(OneVMHelper.get_client)
1047
1057
 
1048
- rc = pool.info_search(:query => options[:search],
1049
- :extended => options[:extended])
1058
+ rc = pool.info_search(
1059
+ :extended => options[:extended], :query => options[:search]
1060
+ )
1050
1061
 
1051
1062
  if !rc.nil?
1052
1063
  puts rc.message
@@ -1068,7 +1079,9 @@ CommandParser::CmdParser.new(ARGV) do
1068
1079
  EOT
1069
1080
 
1070
1081
  command :show, show_desc, :vmid,
1071
- :options => [OpenNebulaHelper::XML, OneVMHelper::ALL_TEMPLATE] do
1082
+ :options => [OpenNebulaHelper::XML,
1083
+ OpenNebulaHelper::DECRYPT,
1084
+ OneVMHelper::ALL_TEMPLATE] do
1072
1085
  helper.show_resource(args[0], options)
1073
1086
  end
1074
1087
 
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -305,7 +311,9 @@ CommandParser::CmdParser.new(ARGV) do
305
311
  EOT
306
312
 
307
313
  command :show, show_desc, :vnetid,
308
- :options => [OpenNebulaHelper::XML, OneVNetHelper::SHOW_AR] do
314
+ :options => [OpenNebulaHelper::XML,
315
+ OpenNebulaHelper::DECRYPT,
316
+ OneVNetHelper::SHOW_AR] do
309
317
  helper.show_resource(args[0], options)
310
318
  end
311
319
 
@@ -421,4 +429,14 @@ CommandParser::CmdParser.new(ARGV) do
421
429
  vnet.unlock
422
430
  end
423
431
  end
432
+
433
+ show_desc = <<-EOT.unindent
434
+ Shows orphans vnets (i.e vnets not referenced in any template).
435
+ EOT
436
+
437
+ command :orphans, show_desc do
438
+ puts helper.check_orphans
439
+
440
+ return 0
441
+ end
424
442
  end
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -20,8 +20,14 @@ ONE_LOCATION = ENV['ONE_LOCATION']
20
20
 
21
21
  if !ONE_LOCATION
22
22
  RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
23
+ GEMS_LOCATION = '/usr/share/one/gems'
23
24
  else
24
25
  RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
26
+ GEMS_LOCATION = ONE_LOCATION + '/share/gems'
27
+ end
28
+
29
+ if File.directory?(GEMS_LOCATION)
30
+ Gem.use_paths(GEMS_LOCATION)
25
31
  end
26
32
 
27
33
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -16,355 +16,753 @@
16
16
 
17
17
  require 'csv'
18
18
 
19
+ # CLI Helper
19
20
  module CLIHelper
21
+
22
+ # CLI general options
20
23
  LIST = {
21
- :name => "list",
22
- :short => "-l x,y,z",
23
- :large => "--list x,y,z",
24
+ :name => 'list',
25
+ :short => '-l x,y,z',
26
+ :large => '--list x,y,z',
24
27
  :format => Array,
25
- :description => "Selects columns to display with list command"
28
+ :description => 'Selects columns to display with list command'
26
29
  }
27
30
 
28
31
  LISTCONF = {
29
- :name => "listconf",
30
- :short => "-c conf",
31
- :large => "--listconf conf",
32
+ :name => 'listconf',
33
+ :short => '-c conf',
34
+ :large => '--listconf conf',
32
35
  :format => String,
33
- :description => "Selects a predefined column list"
36
+ :description => 'Selects a predefined column list'
34
37
  }
35
38
 
36
39
  CSV_OPT = {
37
- :name => "csv",
38
- :large => "--csv",
39
- :description => "Write table in csv format"
40
+ :name => 'csv',
41
+ :large => '--csv',
42
+ :description => 'Write table in csv format'
43
+ }
44
+
45
+ CSV_DEL = {
46
+ :name => 'csv_del',
47
+ :large => '--csv-del del',
48
+ :format => String,
49
+ :description => 'Set delimiter for csv output'
40
50
  }
41
51
 
42
- #ORDER = {
43
- # :name => "order",
44
- # :short => "-o x,y,z",
45
- # :large => "--order x,y,z",
46
- # :format => Array,
47
- # :description => "Order by these columns, column starting with - means decreasing order"
48
- #}
49
- #
50
52
  FILTER = {
51
- :name => "filter",
52
- :short => "-f x,y,z",
53
- :large => "--filter x,y,z",
53
+ :name => 'filter',
54
+ :short => '-f x,y,z',
55
+ :large => '--filter x,y,z',
54
56
  :format => Array,
55
- :description => "Filter data. An array is specified with\n"<<
56
- " "*31<<"column=value pairs."
57
+ :description => "Filter data. An array is specified with\n" <<
58
+ ' ' * 31 << 'column=value pairs.'
57
59
  }
60
+
58
61
  OPERATOR = {
59
- :name => "operator",
60
- :large => "--operator operator",
62
+ :name => 'operator',
63
+ :large => '--operator operator',
61
64
  :format => String,
62
- :description => "Logical operator used on filters: AND, OR."<<
63
- " Default: AND."
65
+ :description => 'Logical operator used on filters: AND, OR. ' \
66
+ 'Default: AND.'
67
+ }
68
+
69
+ NO_HEADER = {
70
+ :name => 'no_header',
71
+ :large => '--no-header',
72
+ :description => 'Hides the header of the table'
64
73
  }
65
-
66
- #
67
- #HEADER = {
68
- # :name => "header",
69
- # :short => "-H",
70
- # :large => "--header",
71
- # :description => "Shows the header of the table"
72
- #}
73
74
 
74
75
  DELAY = {
75
- :name => "delay",
76
- :short => "-d x",
77
- :large => "--delay x",
76
+ :name => 'delay',
77
+ :short => '-d x',
78
+ :large => '--delay x',
78
79
  :format => Integer,
79
- :description => "Sets the delay in seconds for top command"
80
+ :description => 'Sets the delay in seconds for top command'
80
81
  }
81
82
 
82
83
  NO_PAGER = {
83
- :name => "no_pager",
84
- :large => "--no-pager",
85
- :format => String,
86
- :description => "Disable pagination",
87
- :proc => lambda { |o, options|
88
- ENV['ONE_PAGER'] = 'cat' if File.exists?('/bin/cat')
84
+ :name => 'no_pager',
85
+ :large => '--no-pager',
86
+ :description => 'Disable pagination',
87
+ :proc => lambda {|_o, _options|
88
+ ENV['ONE_PAGER'] = 'cat' if File.exist?('/bin/cat')
89
89
  }
90
90
  }
91
91
 
92
- #OPTIONS = [LIST, ORDER, FILTER, HEADER, DELAY]
93
- OPTIONS = [LIST, LISTCONF, DELAY, FILTER, OPERATOR, CSV_OPT, NO_PAGER]
92
+ ADJUST = {
93
+ :name => 'adjust',
94
+ :large => '--adjust x,y,z',
95
+ :format => Array,
96
+ :description => 'Adjust size to not truncate selected columns'
97
+ }
98
+
99
+ SIZE = {
100
+ :name => 'size',
101
+ :short => '-s x=size,y=size',
102
+ :large => '--size x=size,y=size',
103
+ :format => Array,
104
+ :description => 'Change the size of selected columns. ' \
105
+ 'For example: ' \
106
+ '$ onevm list --size "name=20" ' \
107
+ 'will make column name size 20.'
108
+ }
109
+
110
+ EXPAND = {
111
+ :name => 'expand',
112
+ :large => '--expand [x=prop,y=prop]',
113
+ :format => Array,
114
+ :description => 'Expands the columns size to fill the terminal. ' \
115
+ 'For example: ' \
116
+ '$onevm list --expand name=0.4,group=0.6 ' \
117
+ 'will expand name 40% and group 60%. ' \
118
+ '$onevm list --expand name,group ' \
119
+ 'will expand name and group based on its size.' \
120
+ '$onevm list --expand will expand all columns.'
121
+ }
122
+
123
+ NO_EXPAND = {
124
+ :name => 'no_expand',
125
+ :large => '--no-expand',
126
+ :description => 'Disable expand'
127
+ }
128
+
129
+ OPTIONS = [LIST,
130
+ LISTCONF,
131
+ DELAY,
132
+ FILTER,
133
+ OPERATOR,
134
+ CSV_OPT,
135
+ CSV_DEL,
136
+ NO_PAGER,
137
+ NO_HEADER,
138
+ ADJUST,
139
+ SIZE,
140
+ EXPAND,
141
+ NO_EXPAND]
94
142
 
95
143
  # Sets bold font
96
- def CLIHelper.scr_bold
144
+ def self.scr_bold
97
145
  print "\33[1m"
98
146
  end
99
147
 
100
148
  # Sets underline
101
- def CLIHelper.scr_underline
149
+ def self.scr_underline
102
150
  print "\33[4m"
103
151
  end
104
152
 
105
153
  # Restore normal font
106
- def CLIHelper.scr_restore
154
+ def self.scr_restore
107
155
  print "\33[0m"
108
156
  end
109
157
 
110
158
  # Clears screen
111
- def CLIHelper.scr_cls
159
+ def self.scr_cls
112
160
  print "\33[2J\33[H"
113
161
  end
114
162
 
115
163
  # Moves the cursor
116
- def CLIHelper.scr_move(x,y)
117
- print "\33[#{x};#{y}H"
118
- end
119
-
120
- def CLIHelper.scr_red
121
- print "\33[31m"
122
- end
123
-
124
- def CLIHelper.scr_green
125
- print "\33[32m"
164
+ #
165
+ # @param cord_x [Integer] Coordinate x
166
+ # @param cord_y [Integer] Coordinate y
167
+ def self.scr_move(cord_x, cord_y)
168
+ print "\33[#{cord_x};#{cord_y}H"
126
169
  end
127
170
 
128
- ANSI_RED="\33[31m"
129
- ANSI_GREEN="\33[32m"
130
- ANSI_RESET="\33[0m"
131
- ANSI_YELLOW="\33[33m"
171
+ # CLI state colors
172
+ ANSI_RED = "\33[31m"
173
+ ANSI_GREEN = "\33[32m"
174
+ ANSI_RESET = "\33[0m"
175
+ ANSI_YELLOW = "\33[33m"
132
176
 
133
- OK_STATES=%w{runn rdy on configured}
134
- BAD_STATES=%w{fail err err error}
135
- REGULAR_STATES=%w{pending}
177
+ # CLI states
178
+ OK_STATES = %w[runn rdy on configured SUCCESS]
179
+ BAD_STATES = %w[fail err error ERROR]
180
+ REGULAR_STATES = %w[pending]
136
181
 
137
- def CLIHelper.color_state(stat)
182
+ # Set state color
183
+ #
184
+ # @param stat [String] Current state
185
+ def self.color_state(state)
138
186
  if $stdout.tty?
139
- case stat.strip
187
+ case state.strip
140
188
  when *OK_STATES
141
- ANSI_GREEN+stat+ANSI_RESET
189
+ ANSI_GREEN + state + ANSI_RESET
142
190
  when *BAD_STATES
143
- ANSI_RED+stat+ANSI_RESET
191
+ ANSI_RED + state + ANSI_RESET
144
192
  when *REGULAR_STATES
145
- ANSI_YELLOW+stat+ANSI_RESET
193
+ ANSI_YELLOW + state + ANSI_RESET
146
194
  else
147
- stat
195
+ state
148
196
  end
149
197
  else
150
- stat
198
+ state
151
199
  end
152
200
  end
153
201
 
154
202
  # Print header
155
- def CLIHelper.print_header(str, underline=true)
203
+ #
204
+ # @param str [String] String with header content
205
+ # @param underline [Boolean] True to underline the header
206
+ def self.print_header(str, underline = true)
156
207
  if $stdout.tty?
157
208
  print_tty_header(str, underline)
158
209
  else
159
210
  print str
160
211
  end
212
+
161
213
  puts
162
214
  end
163
215
 
164
- # Pretty print header
165
- def CLIHelper.print_tty_header(str, underline=true)
216
+ # Print pretty header
217
+ #
218
+ # @param str [String] String with header content
219
+ # @param underline [Boolean] True to underline the header
220
+ def self.print_tty_header(str, underline = true)
166
221
  scr_bold
167
222
  scr_underline if underline
168
223
  print str
169
224
  scr_restore
170
225
  end
171
226
 
227
+ # Show error message and exit with error
228
+ #
229
+ # @param message [String] Error message to show
230
+ def self.fail(message)
231
+ STDERR.puts message
232
+
233
+ exit(-1)
234
+ end
235
+
236
+ # Check if value is in base64
237
+ #
238
+ # @param value [String] Value to check
239
+ #
240
+ # @return [Boolean] True if it's base64
241
+ def self.base64?(value)
242
+ re = %r(^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)?$)
243
+
244
+ !value.match(re).nil?
245
+ end
246
+
247
+ # Hash with search
172
248
  module HashWithSearch
249
+
250
+ # Search inside path
251
+ #
252
+ # @param path [String] Path to search on
173
253
  def dsearch(path)
174
- stems=path.split('/')
175
- hash=self
254
+ stems = path.split('/')
255
+ hash = self
176
256
 
177
257
  stems.delete_if {|s| s.nil? || s.empty? }
178
258
 
179
259
  stems.each do |stem|
180
- if Hash===hash
260
+ if hash.is_a? Hash
181
261
  if hash[stem]
182
- hash=hash[stem]
262
+ hash = hash[stem]
183
263
  else
184
- hash=nil
264
+ hash = nil
185
265
  break
186
266
  end
187
267
  else
188
- hash=nil
268
+ hash = nil
189
269
  break
190
270
  end
191
271
  end
192
272
 
193
273
  hash
194
274
  end
275
+
195
276
  end
196
277
 
278
+ # Show table
197
279
  class ShowTable
280
+
198
281
  require 'yaml'
199
282
 
200
283
  attr_reader :default_columns
201
284
 
202
- def initialize(conf=nil, ext=nil, &block)
203
- @columns = Hash.new
204
- @default_columns = Array.new
285
+ # Class constructor
286
+ #
287
+ # @param conf [String] Configuration file
288
+ # @param ext [Helper] Cli helper information
289
+ def initialize(conf = nil, ext = nil, &block)
290
+ @columns = {}
291
+ @default_columns = []
205
292
 
206
- @ext = ext
293
+ @ext = ext
207
294
  @conf = conf
208
295
 
209
296
  instance_eval(&block)
210
297
  end
211
298
 
299
+ # Get the helper
212
300
  def helper
213
301
  @ext
214
302
  end
215
303
 
304
+ # Fill column attributes
305
+ #
306
+ # @param name [String] Column name
307
+ # @param desc [String] Column description
308
+ # @param conf [Array] Configutation attributes
216
309
  def column(name, desc, *conf, &block)
217
- column = Hash.new
310
+ column = {}
311
+
218
312
  column[:desc] = desc
219
313
  column[:size] = 5
220
- conf.each{|c|
221
- if c.instance_of?(Symbol)
222
- column[c]=true
223
- elsif c.instance_of?(Hash)
224
- c.each{|key,value|
225
- column[key]=value
226
- }
314
+
315
+ conf.each do |c|
316
+ if c.is_a? Symbol
317
+ column[c] = true
318
+ elsif c.is_a? Hash
319
+ c.each do |key, value|
320
+ column[key] = value
321
+ end
227
322
  end
228
- }
323
+ end
324
+
229
325
  column[:proc] = block
326
+
230
327
  @columns[name.to_sym] = column
231
- @default_columns<<name
328
+
329
+ @default_columns << name
232
330
  end
233
331
 
332
+ # Get default columns
333
+ #
334
+ # @param args [Array] Array with default columns
234
335
  def default(*args)
235
- args.map!{|a| a.to_sym }
236
- @default_columns=args
336
+ args.map! {|a| a.to_sym }
337
+
338
+ @default_columns = args
237
339
  end
238
340
 
239
- def show(data, options={})
240
- update_columns(options)
341
+ # Show resource
342
+ #
343
+ # @param data [Hash/Object] Data to show
344
+ # @param options [Hash] Object with CLI user options
345
+ # @param top [Boolean] True to not update columns again
346
+ def show(data, options = {}, top = false)
347
+ update_columns(options) unless top
348
+
349
+ if data.is_a? Hash
350
+ @data = data
241
351
 
242
- if Hash===data
243
- @data=data
244
352
  @data.extend(HashWithSearch)
245
353
 
246
- pool=@data.keys.first
247
- return print_table(nil, options) if !pool
354
+ pool = @data.keys.first
248
355
 
249
- element=pool.split('_')[0..-2].join('_')
356
+ return print_table(data, options) unless pool
250
357
 
251
- pool_data=@data.dsearch("#{pool}/#{element}")
252
- pool_data=[pool_data].flatten if pool_data
358
+ element = pool.split('_')[0..-2].join('_')
359
+
360
+ pool_data = @data.dsearch("#{pool}/#{element}")
361
+
362
+ if pool_data
363
+ pool_data = [pool_data].flatten
364
+ else
365
+ pool_data = []
366
+ end
253
367
 
254
368
  print_table(pool_data, options)
255
369
  else
370
+ data ||= []
371
+
256
372
  print_table(data, options)
257
373
  end
258
374
  end
259
375
 
260
- def top(options={}, &block)
261
- delay=options[:delay] ? options[:delay] : 1
376
+ # Show resource continuosly
377
+ #
378
+ # @param options [Hash] Object with CLI user options
379
+ def top(options = {})
380
+ delay = options[:delay] || 1
381
+ top = false
262
382
 
263
383
  begin
264
- while true
265
- data = block.call
384
+ loop do
385
+ data = yield
266
386
 
267
387
  CLIHelper.scr_cls
268
- CLIHelper.scr_move(0,0)
388
+ CLIHelper.scr_move(0, 0)
389
+
390
+ show(data, options, top)
269
391
 
270
- show(data, options)
271
392
  sleep delay
393
+
394
+ top = true
272
395
  end
273
- rescue Exception => e
274
- puts e.message
396
+ rescue SystemExit, Interrupt, StandardError => e
397
+ CLIHelper.fail(e.message)
275
398
  end
276
399
  end
277
400
 
401
+ # Show column description
278
402
  def describe_columns
279
- str="%-20s: %-20s"
403
+ str = '%-20s: %-20s'
280
404
 
281
405
  @columns.each do |column, d|
282
- puts str % [column, d[:desc]]
406
+ puts format(str, column, d[:desc])
407
+ end
408
+ end
409
+
410
+ # Get maximum string lenght in column
411
+ #
412
+ # @param index [Integer] Column index to search
413
+ #
414
+ # @return [Integer] Maximum length
415
+ def max_size(index)
416
+ sizes = []
417
+
418
+ @res_data.each do |d|
419
+ sizes << d[index].size
420
+ end
421
+
422
+ sizes.max
423
+ end
424
+
425
+ # Get total size of all columns
426
+ #
427
+ # @param columns [Array] Array with columns name
428
+ #
429
+ # @return [Integer] Total size
430
+ def total_columns_size(columns)
431
+ size = 0
432
+
433
+ columns.each do |c|
434
+ size += @columns[c[:name]][:size]
283
435
  end
436
+
437
+ size
284
438
  end
285
439
 
440
+ # Get columns information
441
+ #
442
+ # @param columns [Array] Array with columns information
443
+ #
444
+ # @return [Array] Array with columns objects
445
+ def columns_info(columns)
446
+ ret = []
447
+
448
+ columns.each do |column|
449
+ data = column.to_s.split('=')
450
+
451
+ ret << { :name => data[0].upcase.to_sym, :prop => data[1] }
452
+ end
453
+
454
+ ret
455
+ end
456
+
457
+ # Print tty header
286
458
  def print_tty_header
287
459
  CLIHelper.print_tty_header(header_str)
460
+
288
461
  puts
289
462
  end
290
463
 
291
464
  private
292
465
 
466
+ # Get header in string format
467
+ def header_str
468
+ @default_columns.collect do |c|
469
+ if @columns[c]
470
+ format_str(c, c.to_s)
471
+ else
472
+ CLIHelper.fail("Column #{c} not defined.")
473
+ end
474
+ end.compact.join(' ')
475
+ end
476
+
477
+ # Print data in table format
478
+ #
479
+ # @param data [Array] Array with data to show
480
+ # @param options [Hash] Object with CLI user options
293
481
  def print_table(data, options)
294
- if !options[:csv] && !options[:noheader]
482
+ @res_data = data_array(data, options)
483
+
484
+ update_columns_size(options)
485
+
486
+ if !options[:csv] && (!options.key? :no_header)
295
487
  CLIHelper.print_header(header_str)
296
488
  end
297
489
 
298
- data ? print_data(data, options) : puts
490
+ if options[:csv] && (!options.key? :no_header)
491
+ print_csv_data([@default_columns], options[:csv_del])
492
+ end
493
+
494
+ @res_data ? print_data(@res_data, options) : puts
299
495
  end
300
496
 
497
+ # Print data
498
+ #
499
+ # @param data [Array] Array with data to show
500
+ # @param options [Hash] Object with CLI user options
301
501
  def print_data(data, options)
302
- ncolumns=@default_columns.length
303
- res_data=data_array(data, options)
502
+ if options[:csv]
503
+ print_csv_data(data, options[:csv_del])
504
+ else
505
+ print_normal_data(data, options[:stat_column])
506
+ end
507
+ rescue Errno::EPIPE => e
508
+ CLIHelper.fail(e.message)
509
+ end
304
510
 
305
- if options[:stat_column]
306
- stat_column=@default_columns.index(
307
- options[:stat_column].upcase.to_sym)
511
+ # Print data in CSV format
512
+ #
513
+ # @param data [Array] Array with data to show
514
+ # @param del [Char] CSV delimiter
515
+ def print_csv_data(data, del)
516
+ del ? del = del : del = ','
517
+
518
+ data.each do |l|
519
+ puts CSV.generate_line(l, :col_sep => del)
520
+ end
521
+ end
522
+
523
+ # Print data in normal format
524
+ #
525
+ # @param data [Array] Array with data to show
526
+ # @param stat_column [String] Name of the state column
527
+ def print_normal_data(data, stat_column)
528
+ ncolumns = @default_columns.length
529
+
530
+ if stat_column
531
+ stat = stat_column.upcase.to_sym
532
+ stat_column = @default_columns.index(stat)
308
533
  else
309
- stat_column=@default_columns.index(:STAT)
534
+ stat_column = @default_columns.index(:STAT)
310
535
  end
311
536
 
312
- begin
313
- if options[:csv]
314
- puts CSV.generate_line(@default_columns) if !options[:noheader]
315
- res_data.each {|l| puts CSV.generate_line(l) }
316
- else
317
- res_data.each{|l|
318
- puts (0..ncolumns-1).collect{ |i|
319
- dat=l[i]
320
- col=@default_columns[i]
537
+ data.each do |l|
538
+ result = []
539
+
540
+ ncolumns.times do |i|
541
+ dat = l[i]
542
+ col = @default_columns[i]
543
+
544
+ str = format_str(col, dat)
321
545
 
322
- str=format_str(col, dat)
323
- str=CLIHelper.color_state(str) if i==stat_column
546
+ str = CLIHelper.color_state(str) if i == stat_column
324
547
 
325
- str
326
- }.join(' ').rstrip
327
- }
548
+ result << str
328
549
  end
329
- rescue Errno::EPIPE
550
+ puts result.join(' ').rstrip
330
551
  end
331
552
  end
332
553
 
554
+ # Get data in array format
555
+ #
556
+ # @param data [Array] Array with data to show
557
+ # @param options [Hash] Object with CLI user options
558
+ #
559
+ # @return [Array] Array with selected columns information
333
560
  def data_array(data, options)
334
- res_data=data.collect {|d|
335
- @default_columns.collect {|c|
561
+ res_data = data.collect do |d|
562
+ @default_columns.collect do |c|
336
563
  @columns[c][:proc].call(d).to_s if @columns[c]
337
- }
338
- }
564
+ end
565
+ end
339
566
 
340
567
  if options
341
568
  filter_data!(res_data, options) if options[:filter]
342
- sort_data!(res_data, options[:order]) if options[:order]
343
569
  end
344
570
 
345
571
  res_data
346
572
  end
347
573
 
574
+ # Format data as string
575
+ #
576
+ # @param field [Symbol] Name of the column to format
577
+ # @param data [String] Data to format
348
578
  def format_str(field, data)
349
579
  if @columns[field]
350
- minus=( @columns[field][:left] ? "-" : "" )
351
- size=@columns[field][:size]
352
- if @columns[field][:donottruncate]
353
- return "%#{minus}#{size}s" % [ data.to_s ]
580
+ @columns[field][:left] ? minus = '-' : minus = ''
581
+ size = @columns[field][:size]
582
+
583
+ if @columns[field][:adjust]
584
+ format("%#{minus}#{size}s", data.to_s)
585
+ else
586
+ format("%#{minus}#{size}.#{size}s", data.to_s)
354
587
  end
355
- return "%#{minus}#{size}.#{size}s" % [ data.to_s ]
356
588
  else
357
- exit -1, "Column #{field} not defined."
589
+ CLIHelper.fail("Column #{field} not defined.")
358
590
  end
359
591
  end
360
592
 
593
+ # Get expand information from configuration files
594
+ #
595
+ # @return [Array] Array with columns data
596
+ def config_expand_data
597
+ ret = []
598
+
599
+ @default_columns.each do |column|
600
+ expand_c = @columns[column][:expand]
601
+
602
+ next unless expand_c
603
+
604
+ column = column.to_s.downcase
605
+
606
+ ret << "#{column}=#{expand_c}" if expand_c.is_a? Numeric
607
+
608
+ ret << column.to_s.downcase unless expand_c.is_a? Numeric
609
+ end
610
+
611
+ ret
612
+ end
613
+
614
+ # Get adjust information from configuration files
615
+ #
616
+ # @return [Array] Array with columns data
617
+ def config_adjust_data
618
+ ret = []
619
+
620
+ @default_columns.each do |column|
621
+ next unless @columns[column][:adjust]
622
+
623
+ ret << column.to_s.downcase
624
+ end
625
+
626
+ ret
627
+ end
628
+
629
+ # Change the size of expand columns
630
+ #
631
+ # @param expand_columns [Array] Array with expand columns names
632
+ # @param all [Boolean] True to expand all columns
633
+ def expand_columns(expand_columns, all = false)
634
+ return if expand_columns.empty?
635
+
636
+ if $stdout.tty?
637
+ terminal_size = IO.console.winsize[1]
638
+ else
639
+ terminal_size = nil
640
+ end
641
+
642
+ return if terminal_size.nil?
643
+
644
+ default_columns = columns_info(@default_columns)
645
+ expand_columns = columns_info(expand_columns)
646
+
647
+ total_size = total_columns_size(default_columns)
648
+ columns_size = total_columns_size(expand_columns)
649
+
650
+ terminal_size -= (@default_columns.size - 1)
651
+ left_size = terminal_size - total_size
652
+ remaining_size = left_size
653
+
654
+ return if left_size <= 0
655
+
656
+ expand_columns.each do |c|
657
+ column = c[:name]
658
+ prop = c[:prop]
659
+
660
+ if @columns[column].nil?
661
+ CLIHelper.fail("Unknown column #{column}")
662
+ end
663
+
664
+ if all
665
+ prop = @columns[column][:size] / total_size.to_f
666
+ elsif !prop
667
+ prop = @columns[column][:size] / columns_size.to_f
668
+ end
669
+
670
+ size = (left_size * prop.to_f).round
671
+
672
+ @columns[column][:adjust] = false
673
+ @columns[column][:size] += size
674
+
675
+ remaining_size -= size
676
+ end
677
+
678
+ if remaining_size > 0
679
+ # If there is some left space, add it to the last column
680
+ @columns[expand_columns[-1][:name]][:size] += remaining_size
681
+ end
682
+
683
+ return if terminal_size == total_columns_size(default_columns)
684
+
685
+ # If there is extra space, sub it from the last column
686
+ diff = total_columns_size(default_columns) - terminal_size
687
+
688
+ @columns[expand_columns[-1][:name]][:size] -= diff
689
+ end
690
+
691
+ # Change columns size
692
+ #
693
+ # @param options [Array] Array with size information for each column
694
+ def size_columns(options)
695
+ options[:size].each do |column|
696
+ data = column.split('=')
697
+ column = data[0].upcase.to_sym
698
+ size = data[1].to_i
699
+
700
+ @columns[column][:adjust] = false
701
+ @columns[column][:size] = size
702
+ end
703
+ end
704
+
705
+ # Update columns size information
706
+ #
707
+ # @param options [Hash] Object with CLI user options
708
+ def update_columns_size(options)
709
+ adjust = options[:adjust]
710
+
711
+ if adjust
712
+ adjust += config_adjust_data
713
+ else
714
+ adjust = config_adjust_data
715
+ end
716
+
717
+ expand_all = (options.key? :expand) && options[:expand].nil?
718
+ expand = !options[:expand].nil?
719
+ expand_data = []
720
+
721
+ if expand_all
722
+ expand_data = @default_columns
723
+ elsif expand
724
+ expand_data += options[:expand]
725
+ end
726
+
727
+ expand_data += config_expand_data
728
+
729
+ c_size = options[:size]
730
+
731
+ # Update adjust attribute to not truncate the column
732
+ # If expand all columns adjust is ignored
733
+ unless expand_all
734
+ adjust.each do |column|
735
+ column = column.upcase.to_sym
736
+ size = max_size(@default_columns.index(column))
737
+
738
+ if size && size > @columns[column][:size]
739
+ @columns[column][:adjust] = true
740
+ @columns[column][:size] = size
741
+ end
742
+ end
743
+ end
744
+
745
+ # Update size attribute if size
746
+ size_columns(options) if c_size
747
+
748
+ # Update size attribute if expand
749
+ expand_columns(expand_data) unless options.key? :no_expand
750
+ end
751
+
752
+ # Update columns information
753
+ #
754
+ # @param options [Hash] Object with CLI user options
361
755
  def update_columns(options)
362
756
  begin
363
- config = YAML.load_file(@conf)
757
+ if @conf
758
+ config = YAML.load_file(@conf)
759
+ else
760
+ config = {}
761
+ end
364
762
 
365
- default = config.delete(:default)
763
+ default = config.delete(:default) || {}
366
764
  default_conf = config.delete(:default_conf) || {}
367
- listconf = options[:listconf]
765
+ listconf = options[:listconf]
368
766
 
369
767
  listconf = default_conf[listconf.to_sym] if listconf
370
768
 
@@ -381,75 +779,69 @@ module CLIHelper
381
779
  # Filter show options with available columns
382
780
  @default_columns &= @columns.keys
383
781
 
384
- @columns.merge!(config) { |key, oldval, newval|
782
+ @columns.merge!(config) do |_key, oldval, newval|
385
783
  oldval.merge(newval)
386
- }
387
- rescue Exception => e
784
+ end
785
+ rescue StandardError => e
786
+ CLIHelper.fail(e.message)
388
787
  end
389
788
 
390
- @default_columns = options[:list].collect{|o| o.to_sym} if options[:list]
391
- end
789
+ return unless options[:list]
392
790
 
393
- def header_str
394
- @default_columns.collect {|c|
395
- if @columns[c]
396
- format_str(c, c.to_s)
397
- else
398
- puts "Column #{c} not defined."
399
- exit -1
400
- end
401
- }.compact.join(' ')
791
+ @default_columns = options[:list].collect {|o| o.upcase.to_sym }
402
792
  end
403
793
 
794
+ # Filter data
795
+ #
796
+ # @param data [Array] Array with data to filter
797
+ # @param options [Hash] Object with CLI user options
404
798
  def filter_data!(data, options)
405
- # TBD: add more operators
406
- # operators=/(==|=|!=|<|<=|>|>=)/
407
- operators=/(=|!=)/
408
- filter = options[:filter]
799
+ operators = /(=|!=|<|<=|>|>=)/
800
+ filter = options[:filter]
801
+
409
802
  if options.key?(:operator)
410
- log_operator = options[:operator].upcase
803
+ log_operator = options[:operator].upcase
411
804
  else
412
- log_operator = "AND"
805
+ log_operator = 'AND'
413
806
  end
414
807
 
415
- stems=filter.map do |s|
416
- m=s.match(/^(.*?)#{operators}(.*?)$/)
808
+ stems = filter.map do |s|
809
+ m = s.match(/^(.*?)#{operators}(.*?)$/)
810
+
417
811
  if m
418
- left, operator, right=m[1..3]
419
- index=@default_columns.index(left.to_sym)
812
+ index = @default_columns.index(m[1].to_sym)
420
813
 
421
814
  if index
422
815
  {
423
- :left => left,
424
- :operator => operator,
425
- :right => right,
816
+ :left => m[1],
817
+ :operator => m[2],
818
+ :right => m[3],
426
819
  :index => index
427
820
  }
428
821
  else
429
- STDERR.puts "Column '#{left}' not found"
430
- exit(-1)
822
+ CLIHelper.fail("Column '#{left}' not found")
431
823
  end
432
824
  else
433
- STDERR.puts "Expression '#{s}' incorrect"
434
- exit(-1)
825
+ CLIHelper.fail("Expression '#{s}' incorrect")
435
826
  end
436
827
  end
437
828
 
438
829
  data.select! do |d|
439
- pass=true
830
+ pass = true
440
831
 
441
832
  stems.each do |s|
833
+ s[:operator] == '=' ? op = '==' : op = s[:operator]
442
834
 
443
- if d[s[:index]].public_send(s[:operator] == "=" ? "==" : s[:operator], s[:right])
444
- if log_operator == "OR"
835
+ if d[s[:index]].public_send(op, s[:right])
836
+ if log_operator == 'OR'
445
837
  pass = true
838
+
446
839
  break
447
840
  end
448
841
  else
449
842
  pass = false
450
- if log_operator == "AND"
451
- break
452
- end
843
+
844
+ break if log_operator == 'AND'
453
845
  end
454
846
  end
455
847
 
@@ -457,6 +849,8 @@ module CLIHelper
457
849
  end
458
850
  end
459
851
 
460
- # TBD def sort_data!
852
+ # TODO: def sort_data!(data, options)
853
+
461
854
  end
855
+
462
856
  end