opennebula-cli 5.8.5 → 5.9.80.pre

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.
@@ -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