launchr 1.1.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.
@@ -0,0 +1,118 @@
1
+
2
+ require 'launchr/service'
3
+
4
+ module Launchr
5
+ # This objects manages all of the commands to be executed by an instance of {Launchr::Application}
6
+ # @see Launchr::Application
7
+ # @see Launchr::CLI
8
+ class Commands
9
+ PriorityOrder = []
10
+
11
+ def preflight_checks
12
+ unless Launchr::Path.homebrew_prefix
13
+ puts "Preflight checks..."
14
+ raise "No homebrew prefix was found"
15
+ end
16
+ end
17
+
18
+ # To be executed once. Branches out to subroutines, and handles the order-of-execution of
19
+ # those main subrountines.
20
+ def run
21
+ preflight_checks
22
+
23
+ PriorityOrder.each do |command|
24
+ if self.class.method_defined?(command) && ! Launchr.config[:args][command].nil?
25
+ self.send command, Launchr.config[:args][command]
26
+ end
27
+ end
28
+
29
+ left_to_execute = Launchr.config[:args].keys - PriorityOrder
30
+ Launchr.config[:args].each do |command, value|
31
+ if left_to_execute.include?(command) && self.class.method_defined?(command) && ! value.nil?
32
+ self.send command, Launchr.config[:args][command]
33
+ end
34
+ end
35
+ end
36
+
37
+ def cmd cmd, services
38
+ Launchr::Service.cleanup
39
+ services.each do |svc|
40
+ service = Launchr::Service.find(svc)
41
+ service.send(cmd)
42
+ end
43
+ end
44
+
45
+ def start services
46
+ puts "Starting launchd services..."
47
+ cmd :start, services
48
+ end
49
+
50
+ def stop services
51
+ puts "Stopping launchd services..."
52
+ cmd :stop, services
53
+ end
54
+
55
+ def restart services
56
+ puts "Restarting launchd services..."
57
+ cmd :restart, services
58
+ end
59
+
60
+ def info services
61
+ Launchr::Service.cleanup
62
+
63
+ if services.empty?
64
+
65
+ level = Launchr.config[:boot] ? "--boot" : "--user"
66
+ puts "Launchd default target: #{level}"
67
+ puts ""
68
+
69
+ services = Launchr::Service.find_all
70
+ if services.empty?
71
+ puts "No launchd services installed"
72
+ else
73
+ puts Launchr::Service.header
74
+ end
75
+ services.each do |svc|
76
+ svc.send :info
77
+ end
78
+ else
79
+ puts Launchr::Service.header
80
+ services.map! do |svc|
81
+ Launchr::Service.find(svc)
82
+ end
83
+ services.uniq!
84
+
85
+ services.each do |svc|
86
+ svc.send :info
87
+ end
88
+ end
89
+ puts ""
90
+ end
91
+
92
+ def clean value
93
+ puts "Cleaning launchd services..."
94
+ Launchr::Service.cleanup
95
+ puts "Done."
96
+ end
97
+
98
+ def default value
99
+ if Launchr.config[:args][:boot]
100
+ puts "Setting default to --boot"
101
+ Launchr::Path.launchr_default_boot.touch
102
+ Launchr::Path.chown_down Launchr::Path.launchr_default_boot
103
+ Launchr.config[:boot] = true
104
+ else
105
+ puts "Setting default to --user"
106
+ if Launchr::Path.launchr_default_boot.exist?
107
+ Launchr::Path.launchr_default_boot.unlink
108
+ end
109
+ Launchr.config[:boot] = nil
110
+ end
111
+ end
112
+
113
+ def version value
114
+ puts "Launchd commands (for Brew) v#{Launchr.version}"
115
+ end
116
+ end
117
+ end
118
+
@@ -0,0 +1,27 @@
1
+
2
+ require 'pathname'
3
+
4
+ class Pathname
5
+ def include? partial
6
+ self.to_s.include? partial.to_s
7
+ end
8
+
9
+ def chown_R user, group
10
+ require 'fileutils'
11
+ FileUtils.chown_R user, group, self.to_s
12
+ end
13
+
14
+ def user
15
+ Etc.getpwuid(self.stat.uid).name
16
+ end
17
+
18
+ def group
19
+ Etc.getgrgid(self.stat.gid).name
20
+ end
21
+
22
+ def touch
23
+ require 'fileutils'
24
+ FileUtils.touch self.to_s
25
+ end
26
+ end
27
+
@@ -0,0 +1,693 @@
1
+
2
+ require 'optparse'
3
+ require 'optparse/date'
4
+ require 'optparse/shellwords'
5
+ require 'optparse/time'
6
+ require 'optparse/uri'
7
+
8
+ require 'launchr/mixin/ordered_hash'
9
+
10
+ module Launchr
11
+ module Mixlib
12
+ # <tt></tt>
13
+ # Author:: Adam Jacob (<adam@opscode.com>)
14
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
15
+ # License:: Apache License, Version 2.0
16
+ #
17
+ # Licensed under the Apache License, Version 2.0 (the "License");
18
+ # you may not use this file except in compliance with the License.
19
+ # You may obtain a copy of the License at
20
+ #
21
+ # http://www.apache.org/licenses/LICENSE-2.0
22
+ #
23
+ # Unless required by applicable law or agreed to in writing, software
24
+ # distributed under the License is distributed on an "AS IS" BASIS,
25
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26
+ # See the License for the specific language governing permissions and
27
+ # limitations under the License.
28
+ #
29
+ module CLI
30
+ module ClassMethods
31
+ # Add a command line option.
32
+ #
33
+ # === Parameters
34
+ # name<Symbol>:: The name of the option to add
35
+ # args<Hash>:: A hash of arguments for the option, specifying how it should be parsed.
36
+ # === Returns
37
+ # true:: Always returns true.
38
+ def option(name, args)
39
+ @options ||= Launchr::OrderedHash.new
40
+ @options_arguments ||= Launchr::OrderedHash.new
41
+ raise(ArgumentError, "Option name must be a symbol") unless name.kind_of?(Symbol)
42
+
43
+ strip_arg(args,:short)
44
+ strip_arg(args,:long)
45
+
46
+ @options[name.to_sym] = args
47
+ @options_arguments[name.to_sym] = args
48
+ end
49
+
50
+ # Get the hash of current options.
51
+ #
52
+ # === Returns
53
+ # @options<Hash>:: The current options hash.
54
+ def options
55
+ @options ||= Launchr::OrderedHash.new
56
+ @options
57
+ end
58
+
59
+ # Set the current options hash
60
+ #
61
+ # === Parameters
62
+ # val<Hash>:: The hash to set the options to
63
+ #
64
+ # === Returns
65
+ # @options<Hash>:: The current options hash.
66
+ def options=(val)
67
+ raise(ArgumentError, "Options must recieve a hash") unless val.kind_of?(Hash)
68
+ @options = val
69
+ end
70
+
71
+ # Add a command line argument.
72
+ #
73
+ # === Parameters
74
+ # name<Symbol>:: The name of the argument to add
75
+ # args<Hash>:: A hash of arguments for the argument, specifying how it should be parsed.
76
+ # === Returns
77
+ # true:: Always returns true.
78
+ def argument(name, args)
79
+ @arguments ||= Launchr::OrderedHash.new
80
+ @options_arguments ||= Launchr::OrderedHash.new
81
+ raise(ArgumentError, "Argument name must be a symbol") unless name.kind_of?(Symbol)
82
+
83
+ strip_arg(args,:short)
84
+ strip_arg(args,:long)
85
+ convert_argument_to_option(args)
86
+
87
+ @arguments[name.to_sym] = args.dup
88
+ @options_arguments[name.to_sym] = args
89
+ end
90
+
91
+ def strip_arg args, arg
92
+ if args[arg]
93
+ args["#{arg}_strip".to_sym] = args[arg].sub(/\[no-\]/,"").sub(/\s*(\<|\[|=|[A-Z]|[a-zA-z]+\,|\s).*$/,"")
94
+ end
95
+ args
96
+ end
97
+
98
+ def convert_argument_to_option args
99
+ # args = args.dup
100
+ args[:short] = "-" + args[:short] if args[:short]
101
+ args[:short_strip] = "-" + args[:short_strip] if args[:short_strip]
102
+ args[:long] = "--" + args[:long] if args[:long]
103
+ args[:long_strip] = "--" + args[:long_strip] if args[:long_strip]
104
+ args
105
+ end
106
+
107
+ # Get the hash of current arguments.
108
+ #
109
+ # === Returns
110
+ # @arguments<Hash>:: The current arguments hash.
111
+ def arguments
112
+ @arguments ||= Launchr::OrderedHash.new
113
+ @arguments
114
+ end
115
+
116
+ # Set the current arguments hash
117
+ #
118
+ # === Parameters
119
+ # val<Hash>:: The hash to set the arguments to
120
+ #
121
+ # === Returns
122
+ # @arguments<Hash>:: The current arguments hash.
123
+ def arguments=(val)
124
+ raise(ArgumentError, "Arguments must recieve a hash") unless val.kind_of?(Hash)
125
+ @arguments = val
126
+ end
127
+
128
+ # Get the combined hash of combined current options plus current arguments.
129
+ #
130
+ # === Returns
131
+ # @options_arguments<Hash>:: The combined current options and current arguments hash.
132
+ def options_arguments
133
+ @options_arguments ||= Launchr::OrderedHash.new
134
+ @options_arguments
135
+ end
136
+
137
+ # Set the current options and current arguments combined hash
138
+ #
139
+ # === Parameters
140
+ # val<Hash>:: The hash to set the combined options and arguments to
141
+ #
142
+ # === Returns
143
+ # @options_arguments<Hash>:: The current options and current arguments hash.
144
+ def options_arguments=(val)
145
+ raise(ArgumentError, "Options must recieve a hash") unless val.kind_of?(Hash)
146
+ @options_arguments = val
147
+ end
148
+
149
+ # Return the hash of current arguments as human-readable string.
150
+ #
151
+ # === Returns
152
+ # <String>:: The arguments hash, one per line.
153
+ def show_arguments
154
+ @arguments ||= Launchr::OrderedHash.new
155
+ summarize_arguments
156
+ end
157
+
158
+ # Change the banner. Defaults to:
159
+ # Usage: #{0} (options)
160
+ #
161
+ # === Parameters
162
+ # bstring<String>:: The string to set the banner to
163
+ #
164
+ # === Returns
165
+ # @banner<String>:: The current banner
166
+ def banner(bstring=nil)
167
+ case bstring
168
+ when true
169
+ # @banner = "usage: #{File.basename $0} [options]"
170
+ @banner = "Usage: #{File.basename $0} [options]"
171
+ when false
172
+ @banner = ""
173
+ when String
174
+ @banner = bstring
175
+ else
176
+ # @banner ||= "usage: #{File.basename $0} [options]"
177
+ @banner ||= "Usage: #{File.basename $0} [options]"
178
+ # @banner ||= ""
179
+ @banner
180
+ end
181
+ end
182
+
183
+ # Add a line to the header.
184
+ #
185
+ # === Parameters
186
+ # hstring<String>:: The next string to push onto the header
187
+ #
188
+ # === Returns
189
+ # @header<Array>:: The current header, an array of strings
190
+ def header(hstring=nil)
191
+ @header ||= []
192
+ case hstring
193
+ when Array
194
+ @header = hstring
195
+ when String
196
+ @header << hstring
197
+ when nil
198
+ @header
199
+ end
200
+ end
201
+
202
+ # Add a line to the footer.
203
+ #
204
+ # === Parameters
205
+ # fstring<String>:: The next string to push onto the footer
206
+ #
207
+ # === Returns
208
+ # @footer<Array>:: The current footer, an array of strings
209
+ def footer(fstring=nil)
210
+ @footer ||= []
211
+ case fstring
212
+ when Array
213
+ @footer = fstring
214
+ when String
215
+ @footer << fstring
216
+ when nil
217
+ @footer
218
+ end
219
+ end
220
+
221
+ # Summary indent. Passed to option parser. Defaults to: ' ' * 4
222
+ #
223
+ # === Parameters
224
+ # i_string<String>:: Set to the indent string
225
+ #
226
+ # === Returns
227
+ # @summary_indent<String>:: The summary indent
228
+ def summary_indent(i_string=nil)
229
+ if i_string
230
+ @summary_indent = i_string
231
+ else
232
+ @summary_indent ||= ' ' * 4
233
+ @summary_indent
234
+ end
235
+ end
236
+
237
+ # Summary indent. Passed to option parser. Defaults to: 32
238
+ #
239
+ # === Parameters
240
+ # i_string<String>:: Set to the indent string
241
+ #
242
+ # === Returns
243
+ # @summary_indent<String>:: The summary indent
244
+ def summary_width(w_integer=nil)
245
+ if w_integer
246
+ @summary_width = w_integer
247
+ else
248
+ @summary_width ||= 32
249
+ @summary_width
250
+ end
251
+ end
252
+
253
+ # Seperate options with empty lines. Defaults to: false
254
+ #
255
+ # === Parameters
256
+ # bool<true,false>:: Set to true for newline spacing
257
+ #
258
+ # === Returns
259
+ # @spaced_summary<String>:: The current line spacing setting
260
+ def spaced_summary(bool=nil)
261
+ if bool
262
+ @spaced_summary = bool
263
+ else
264
+ @spaced_summary ||= false
265
+ @spaced_summary
266
+ end
267
+ end
268
+
269
+ # The remaining argv command line arguments, after parsing. Defaults to: [] (an empty array) if un-parsed
270
+ #
271
+ # === Returns
272
+ # @filtered_argv<Array>:: The remaining command line arguments, after CLI options parsing.
273
+ def filtered_argv
274
+ @filtered_argv ||= []
275
+ @filtered_argv
276
+ end
277
+ end
278
+
279
+ attr_accessor :options, :arguments, :options_arguments, :config, :banner, :header, :footer
280
+ attr_accessor :opt_parser, :filtered_argv, :summary_indent, :summary_width, :spaced_summary
281
+
282
+ # Create a new Mixlib::CLI class. If you override this, make sure you call super!
283
+ #
284
+ # === Parameters
285
+ # *args<Array>:: The array of arguments passed to the initializer
286
+ #
287
+ # === Returns
288
+ # object<Mixlib::Config>:: Returns an instance of whatever you wanted :)
289
+ def initialize(*args)
290
+ @options = Launchr::OrderedHash.new
291
+ @arguments = Launchr::OrderedHash.new
292
+ @options_arguments = Launchr::OrderedHash.new
293
+ @config = Hash.new
294
+ @filtered_argv = []
295
+
296
+ # Set the banner
297
+ @banner = self.class.banner
298
+ @header = self.class.header
299
+ @footer = self.class.footer
300
+
301
+ @summary_indent = self.class.summary_indent
302
+ @summary_width = self.class.summary_width
303
+ @spaced_summary = self.class.spaced_summary
304
+
305
+ # Dupe the class options for this instance
306
+ klass_options = self.class.options
307
+ klass_options.keys.inject(@options) { |memo, key| memo[key] = klass_options[key].dup; memo }
308
+
309
+ # Dupe the class arguments for this instance
310
+ klass_arguments = self.class.arguments
311
+ klass_arguments.keys.inject(@arguments) { |memo, key| memo[key] = klass_arguments[key].dup; memo }
312
+
313
+ # Dupe the class arguments for this instance
314
+ klass_options_arguments = self.class.options_arguments
315
+ klass_options_arguments.keys.inject(@options_arguments) { |memo, key| memo[key] = klass_options_arguments[key].dup; memo }
316
+
317
+ # check argument and option :name keys dont conflict
318
+ name_collision = klass_options.keys & klass_arguments.keys
319
+ raise ArgumentError, "An option cannot have the same name as an argument: #{name_collision.join(', ')}" unless name_collision.empty?
320
+
321
+ koso, kolo = [], []
322
+ klass_options.each do |name, kargs|
323
+ koso << (kargs[:short_strip] || "")
324
+ kolo << (kargs[:long_strip] || "")
325
+ end
326
+
327
+ kasa, kala = [], []
328
+ klass_arguments.each do |name, kargs|
329
+ kasa << (kargs[:short_strip] || "")
330
+ kala << (kargs[:long_strip] || "")
331
+ end
332
+
333
+ # Check that argument an option --long switches dont conflict
334
+ loa_collision = kolo & kala - [""]
335
+ opt_name = klass_options.keys[kolo.index(loa_collision.first) || 0]
336
+ arg_name = klass_arguments.keys[kala.index(loa_collision.first) || 0]
337
+ raise ArgumentError, "Collision: switch '#{loa_collision.first}' for option(#{opt_name.inspect}) and argument(#{arg_name.inspect}) cannot be the same" unless loa_collision.empty?
338
+
339
+ # Check that argument an option -s short switches dont conflict
340
+ soa_collision = koso & kasa - [""]
341
+ opt_name = klass_options.keys[kolo.index(soa_collision.first) || 0]
342
+ arg_name = klass_arguments.keys[kala.index(soa_collision.first) || 0]
343
+ raise ArgumentError, "Collision: switch '#{soa_collision.first}' for option(#{opt_name.inspect}) and argument(#{arg_name.inspect}) cannot be the same" unless soa_collision.empty?
344
+
345
+ # Set the default configuration values for this instance
346
+ @options.each do |config_key, config_opts|
347
+ config_opts[:on] ||= :on
348
+ config_opts[:boolean] ||= false
349
+ config_opts[:requires] ||= nil
350
+ config_opts[:proc] ||= nil
351
+ config_opts[:show_options] ||= false
352
+ config_opts[:exit] ||= nil
353
+
354
+ if config_opts.has_key?(:default)
355
+ @config[config_key] = config_opts[:default]
356
+ end
357
+ end
358
+
359
+ @arguments.each do |config_key, config_opts|
360
+ config_opts[:on] ||= :on
361
+ config_opts[:boolean] ||= false
362
+ config_opts[:requires] ||= nil
363
+ config_opts[:proc] ||= nil
364
+ config_opts[:show_options] ||= false
365
+ config_opts[:exit] ||= nil
366
+
367
+ if config_opts.has_key?(:default)
368
+ @config[config_key] = config_opts[:default]
369
+ end
370
+ end
371
+
372
+ @options_arguments.each do |config_key, config_opts|
373
+ config_opts[:on] ||= :on
374
+ config_opts[:boolean] ||= false
375
+ config_opts[:requires] ||= nil
376
+ config_opts[:proc] ||= nil
377
+ config_opts[:show_options] ||= false
378
+ config_opts[:exit] ||= nil
379
+
380
+ if config_opts.has_key?(:default)
381
+ @config[config_key] = config_opts[:default]
382
+ end
383
+ end
384
+
385
+ super(*args)
386
+ end
387
+
388
+
389
+ def guess_and_switchify_arguments argv
390
+ # collect argument declarations
391
+ short_args = @arguments.values.map { |args| args[:short_strip] }
392
+ long_args = @arguments.values.map { |args| args[:long_strip] }
393
+
394
+ short_opts_args = @options_arguments.values.map { |args| args[:short_strip] }
395
+ long_opts_args = @options_arguments.values.map { |args| args[:long_strip] }
396
+
397
+ short_opts_args_unfiltered = @options_arguments.values.map { |args| args[:short] }
398
+ long_opts_args_unfiltered = @options_arguments.values.map { |args| args[:long] }
399
+
400
+ i = 0
401
+ while i < argv.size
402
+
403
+ # switchify the argv argument if it looks like a recognised argument
404
+ if short_args.include?("-"+argv[i].sub(/^no-/,"").sub(/(=|\s).*/,""))
405
+ argv[i] = "-" + argv[i]
406
+ end
407
+
408
+ if long_args.include?("--"+argv[i].sub(/^no-/,"").sub(/(=|\s).*/,""))
409
+ argv[i] = "--" + argv[i]
410
+ end
411
+
412
+ # when the argv argument matches a recognised option or argument
413
+ # without the style =value, the following argument might have to be skipped...
414
+
415
+ # so find the index of the switch declaration
416
+ j = nil
417
+ if short_opts_args.include?(argv[i])
418
+ j = short_opts_args.index(argv[i])
419
+ end
420
+ if long_opts_args.include?(argv[i])
421
+ j = long_opts_args.index(argv[i])
422
+ end
423
+
424
+ if j
425
+ # when the switch declaration has a required argument
426
+ if short_opts_args_unfiltered[j] =~ /( .+|\<|\=|[A-Z])/
427
+ # skip forward one
428
+ i += 1
429
+ end
430
+ # when the switch declaration has a required argument
431
+ if long_opts_args_unfiltered[j] =~ /( .+|\<|\=|[A-Z])/
432
+ # skip forward one
433
+ i += 1
434
+ end
435
+ end
436
+ # next argument
437
+ i += 1
438
+ end
439
+
440
+ argv
441
+ end
442
+
443
+ # Parses an array, by default ARGV, for command line options (as configured at
444
+ # the class level).
445
+ # === Parameters
446
+ # argv<Array>:: The array of arguments to parse; defaults to ARGV
447
+ #
448
+ # === Returns
449
+ # argv<Array>:: Returns any un-parsed elements.
450
+ def parse_options(argv=ARGV)
451
+ argv = argv.dup
452
+ argv = guess_and_switchify_arguments(argv)
453
+ @opt_parser = OptionParser.new do |opts|
454
+ # Set the banner
455
+ opts.banner = banner
456
+
457
+ # Create new options
458
+ options_arguments.each do |opt_key, opt_val|
459
+ opt_args = build_option_arguments(opt_val)
460
+
461
+ opt_method = case opt_val[:on]
462
+ when :on
463
+ :on
464
+ when :tail
465
+ :on_tail
466
+ when :head
467
+ :on_head
468
+ else
469
+ raise ArgumentError, "You must pass :on, :tail, or :head to :on"
470
+ end
471
+
472
+ parse_block = \
473
+ Proc.new() do |*c|
474
+ if c.empty? || c == [nil]
475
+ c = true
476
+ config[opt_key] = (opt_val[:proc] && opt_val[:proc].call(c)) || c
477
+ else
478
+ c = c.first
479
+ config[opt_key] = (opt_val[:proc] && opt_val[:proc].call(c)) || c
480
+ end
481
+ puts filter_options_summary(opts.to_s) if opt_val[:show_options]
482
+ exit opt_val[:exit] if opt_val[:exit]
483
+ end
484
+
485
+ # opts.send(:on, *[opt_method,*opt_args, parse_block])
486
+ opt_args.unshift opt_method
487
+ opt_args << parse_block
488
+ opts.send(*opt_args)
489
+ end
490
+ end
491
+
492
+ @opt_parser.summary_indent = @summary_indent if @summary_indent
493
+ @opt_parser.summary_width = @summary_width if @summary_width
494
+
495
+ @opt_parser.parse!(argv)
496
+ @filtered_argv = argv
497
+
498
+ # Deal with any required values
499
+ fail = nil
500
+ options_arguments.each do |opt_key, opt_value|
501
+ next unless config[opt_key]
502
+ # next if config[opt_key] == opt_value[:default]
503
+
504
+ reqargs = []
505
+ case opt_value[:requires]
506
+ when nil
507
+ when Proc
508
+ begin
509
+ result = opt_value[:requires].call(config)
510
+ rescue
511
+ reqargs << $!.message
512
+ end
513
+ reqargs << result if result.class == String
514
+ when Array,Symbol
515
+ required_opts = [opt_value[:requires]].flatten
516
+ required_opts.each do |required_opt|
517
+ reqargs << required_opt.to_sym unless config[required_opt.to_sym]
518
+ end
519
+
520
+ reqargs.map! do |opt|
521
+ arg = (options_arguments[opt][:long_strip] || options_arguments[opt][:short_strip]).dup
522
+ arg.gsub!(/^-+/,"") if arguments.keys.include?(opt)
523
+ arg
524
+ end
525
+ end
526
+ unless reqargs.empty?
527
+ fail = true
528
+ opt = (opt_value[:long_strip] || opt_value[:short_strip]).dup
529
+ opt.gsub!(/^-+/,"") if arguments.keys.include?(opt_key)
530
+ puts "You must supply #{reqargs.join(", ")} with #{opt}!"
531
+ end
532
+
533
+ end
534
+ if fail
535
+ puts filter_options_summary(@opt_parser.to_s)
536
+ exit 2
537
+ end
538
+
539
+ argv
540
+ end
541
+
542
+ def build_option_arguments(opt_setting)
543
+ arguments = Array.new
544
+ arguments << opt_setting[:short] if opt_setting.has_key?(:short)
545
+ arguments << opt_setting[:long] if opt_setting.has_key?(:long)
546
+
547
+ if opt_setting.has_key?(:keywords)
548
+ arguments << opt_setting[:keywords]
549
+
550
+ elsif opt_setting.has_key?(:type)
551
+ arguments << opt_setting[:type]
552
+ end
553
+
554
+ case opt_setting[:description]
555
+ when Array
556
+ lines = opt_setting[:description].dup
557
+ # lines.first << " (required)" if opt_setting[:required]
558
+ lines.map! do |line|
559
+ if line == lines.first
560
+ line
561
+ else
562
+ line = " " + line if opt_setting[:indent]
563
+ @spaced_summary ? line : " " + line
564
+ end
565
+ end
566
+ arguments += lines
567
+ when String
568
+ description = opt_setting[:description]
569
+ # description = " " + description if opt_setting[:indent]
570
+ # description << " (required)" if opt_setting[:required]
571
+ arguments << description
572
+ end
573
+
574
+ case opt_setting[:example]
575
+ when Array
576
+ lines = opt_setting[:example]
577
+ example = lines.map do |line|
578
+ if line == lines.first
579
+ header = "Examples $ "
580
+ header = " " + header unless @spaced_summary
581
+ else
582
+ header = " $ "
583
+ header = " " + header unless @spaced_summary
584
+ end
585
+ header = " " + header if opt_setting[:indent]
586
+
587
+ line_parts = line.split("#")
588
+ if line_parts.first.include?("#{File.basename($0)} ")
589
+ header + line
590
+ else
591
+ header + "#{File.basename $0} " + line
592
+ end
593
+ end
594
+ arguments << " " if @spaced_summary
595
+ arguments += example
596
+ when /#{File.basename $0}/
597
+ line = opt_setting[:example]
598
+ line_parts = line.split("#")
599
+ if line_parts.first.include?("#{File.basename($0)} ")
600
+ line = "Example $ " + line
601
+ line = " " + line if opt_setting[:indent]
602
+ else
603
+ line = "Example $ #{File.basename $0} " + line
604
+ line = " " + line if opt_setting[:indent]
605
+ end
606
+ line = " " + line unless @spaced_summary
607
+ arguments << line
608
+ when nil
609
+ else
610
+ line = "Example $ #{File.basename $0} " + opt_setting[:example]
611
+ line = " " + line if opt_setting[:indent]
612
+ line = " " + line unless @spaced_summary
613
+ arguments << line
614
+ end
615
+
616
+ arguments
617
+ end
618
+
619
+ def filter_options_summary options_summary
620
+ os = options_summary.split("\n")
621
+ out = []
622
+
623
+ short_args = @arguments.values.map do |args|
624
+ args[:short] ? args[:short].sub(/([A-Z]|=|\s).*$/,"") : args[:short]
625
+ end
626
+ long_args = @arguments.values.map do |args|
627
+ args[:long] ? args[:long].sub(/([A-Z]|=|\s).*$/,"") : args[:long]
628
+ end
629
+
630
+ os.each do |line|
631
+ case line
632
+ when banner
633
+ out += [@header].flatten if @header
634
+ unless line =~ /^\s*$/
635
+ # line = " " + line if @spaced_summary
636
+ out << line
637
+ end
638
+ else
639
+ if @spaced_summary
640
+ out << "" unless line =~ /^#{@opt_parser.summary_indent}\s{#{@opt_parser.summary_width},}/
641
+ end
642
+
643
+ line =~ /^\s+-((\[no-\])?\w+)\,?/
644
+ short_opt = $1 || false
645
+ line =~ /^\s+(-(\[no-\])?\w+\,?)?\s--((\[no-\])?\w+)/
646
+ long_opt = $3 || false
647
+
648
+ # line.sub!("-"+short_opt," "+short_opt) if short_opt && short_args.include?("-#{short_opt}")
649
+ # line.sub!("--"+long_opt," "+long_opt) if long_opt && long_args.include?("--#{long_opt}")
650
+
651
+ opt_value = {}
652
+ @options_arguments.each do |key,value|
653
+ if long_opt && value[:long_strip]
654
+ if long_opt.sub(/^(-+)?\[no-\]/,"") == value[:long_strip].sub(/^-+/,"")
655
+ # puts long_opt
656
+ opt_value = value
657
+ end
658
+ elsif short_opt && value[:short_strip]
659
+ if short_opt.sub(/^(-+)?\[no-\]/,"") == value[:short_strip].sub(/^-+/,"")
660
+ # puts short_opt
661
+ opt_value = value
662
+ end
663
+ end
664
+ end
665
+ line = " " + line if opt_value[:indent]
666
+
667
+ if short_opt && short_args.include?("-#{short_opt}")
668
+ short_opt = @arguments.values[short_args.index("-#{short_opt}")][:short].sub(/^-+/,"")
669
+ # short_opt = opt_value[:short].sub(/^-+/,"")
670
+ line.sub!("-"+short_opt,short_opt+" ")
671
+ end
672
+ if long_opt && long_args.include?("--#{long_opt}")
673
+ long_opt = @arguments.values[long_args.index("--#{long_opt}")][:long].sub(/^-+/,"")
674
+ # long_opt = opt_value[:short].sub(/^-+/,"")
675
+ line.sub!("--"+long_opt,long_opt+" ")
676
+ end
677
+
678
+ out << line
679
+ end
680
+ end
681
+ out << " " if @spaced_summary
682
+ out += [@footer].flatten if @footer
683
+
684
+ out
685
+ end
686
+
687
+ def self.included(receiver)
688
+ receiver.extend(Mixlib::CLI::ClassMethods)
689
+ end
690
+
691
+ end
692
+ end
693
+ end