commandline 0.7.9

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.
data/docs/tmp/app1.rb ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'commandline'
4
+
5
+ class App < CommandLine::Application
6
+
7
+ def main
8
+ puts "running"
9
+ end
10
+
11
+ end#class App
data/docs/tmp/app1b.rb ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'commandline'
4
+
5
+ class App < CommandLine::Application
6
+
7
+ def initialize
8
+ options :help, :debug
9
+ end
10
+
11
+ def main
12
+ puts "running"
13
+ end
14
+
15
+ end#class App
data/docs/tmp/app2.rb ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'commandline'
4
+
5
+ class App < CommandLine::Application
6
+
7
+ def initialize
8
+ synopsis "[-dh] file"
9
+ expected_args :file
10
+ end
11
+
12
+ def main
13
+ puts "#{name} called with #{args.size} arguments: #{args.inspect}"
14
+ puts "@file = #{@file}"
15
+ end
16
+
17
+ end#class App
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'commandline'
5
+
6
+ class App < CommandLine::Application
7
+ def initialize
8
+ options :help, :debug
9
+ option :names => "--file", :opt_found => get_args
10
+ end
11
+
12
+ def main
13
+ puts "--file: #{opt :file}"
14
+ at_exit { puts "in main" }
15
+ end
16
+ end#class App
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'commandline'
5
+
6
+ class App < CommandLine::Application
7
+ def initialize
8
+ author "Author Name"
9
+ copyright "Author Name, 2005"
10
+ synopsis "[-dh] [--in-file <in_file>] file"
11
+ short_description "Example application with one arg"
12
+ long_description "put your long description here!"
13
+ options :help, :debug
14
+ option :names => "--in-file", :opt_found => get_args,
15
+ :opt_description => "Input file for sample app.",
16
+ :arg_description => "input_file"
17
+ expected_args :file
18
+ end
19
+
20
+ def main
21
+ puts "args: #{args}"
22
+ puts "--in-file: #{opt "--in-file"}"
23
+ end
24
+ end#class App
@@ -0,0 +1,12 @@
1
+
2
+ require 'rubygems'
3
+ require 'commandline'
4
+
5
+ class App < CommandLine::Application
6
+ def initialize
7
+ option :flag, :names => %w(--my-flag -m)
8
+ option :help
9
+ end
10
+ end
11
+
12
+
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ require 'commandline'
3
+ require 'rubygems'
4
+
5
+ class App < CommandLine::Application
6
+ def initialize
7
+ use_replay
8
+ option :help, :debug
9
+ expected_args :input, :output
10
+ end
11
+
12
+ def main
13
+ p @arg_names
14
+ puts "#{name} called with #{@args.size} arguments: #{@args.inspect}"
15
+ puts "input: #{@input}"
16
+ puts "output: #{@output}"
17
+ end
18
+
19
+ end#class App
@@ -0,0 +1,16 @@
1
+ # $Id: commandline.rb,v 1.2 2005/09/19 19:53:36 jdf Exp $
2
+ # $Source: /Users/jdf/projects/CVSROOT/devel/ruby/commandline/lib/commandline.rb,v $
3
+ #
4
+ # Author: Jim Freeze
5
+ # Copyright (c) 2005
6
+ #
7
+ # =DESCRIPTION
8
+ # Loader
9
+ #
10
+ # =Revision History
11
+ # Jim.Freeze 2005/06/17 Birthday
12
+ #
13
+
14
+ require 'commandline/kernel'
15
+ require 'commandline/utils'
16
+ require 'commandline/application'
@@ -0,0 +1,437 @@
1
+ # $Id: application.rb,v 1.4 2005/09/20 19:11:17 jdf Exp $
2
+ # $Source: /Users/jdf/projects/CVSROOT/devel/ruby/commandline/lib/commandline/application.rb,v $
3
+ #
4
+ # Author: Jim Freeze
5
+ # Copyright (c) 2005
6
+ #
7
+ # =DESCRIPTION
8
+ # Framework for commandline applications
9
+ #
10
+ # =Revision History
11
+ # Jim.Freeze 06/02/2005 Birthday - kinda
12
+ # Jim.Freeze 09/19/2005 fixed @arg_arity bug and copyright print bug
13
+
14
+ require 'commandline/utils'
15
+ require 'commandline/optionparser'
16
+
17
+ module CommandLine
18
+ class Application
19
+ class ApplicationError < StandardError; end
20
+ class OptionError < ApplicationError; end
21
+ class MissingMainError < ApplicationError; end
22
+ class InvalidArgumentArityError < ApplicationError; end
23
+ class ArgumentError < ApplicationError; end
24
+ class UnknownOptionError < ApplicationError; end
25
+
26
+ param_accessor :version, :author, :copyright, :synopsis,
27
+ :short_description, :long_description,
28
+ :option_parser
29
+
30
+ attr_reader :args, :argv
31
+
32
+ @no_auto_run = false
33
+
34
+ #
35
+ # TODO: Consolidate these with OptionParser - put in command line
36
+ #
37
+ DEFAULT_CONSOLE_WIDTH = 70
38
+ MIN_CONSOLE_WIDTH = 10
39
+ DEFAULT_BODY_INDENT = 4
40
+
41
+ def initialize
42
+ @synopsis = ""
43
+ @arg_arity = [0,0]
44
+ @options = []
45
+ @arg_names = []
46
+ @args = []
47
+ @replay = false
48
+ @replay_file = ".replay"
49
+
50
+ __initialize_text_formatting
51
+
52
+ # Call the child usurped initialize
53
+ __child_initialize if
54
+ self.class.private_instance_methods(false).include?("__child_initialize")
55
+
56
+ @option_parser ||= CommandLine::OptionParser.new(@options)
57
+ end
58
+
59
+ def options(*opts)
60
+ opts.each { |opt| option(*[opt].flatten) }
61
+ end
62
+
63
+ def option(*args)
64
+ @options ||= []
65
+ new_list = []
66
+ args.each { |arg|
67
+ new_list <<
68
+ case arg
69
+ when :help then __help
70
+ when :debug then __debug
71
+ when :verbose then __verbose
72
+ when :version then __version
73
+ else arg
74
+ end
75
+ }
76
+ #p new_list
77
+ @options << CommandLine::Option.new(*new_list)
78
+ end
79
+
80
+ # Alternative for @option_data["<--opt>"], but with symbols
81
+ def opt(name)
82
+ if name.kind_of?(Symbol)
83
+ o1 = "--#{name}"
84
+ o2 = "-#{name}"
85
+ if @option_data.has_option?(o1)
86
+ @option_data[o1]
87
+ elsif @option_data.has_option?(o2)
88
+ @option_data[o2]
89
+ else
90
+ raise UnknownOptionError, "Unknown options '#{o1}' and '#{o2}'."
91
+ end
92
+ else
93
+ raise UnknownOptionError, "Unknown option '#{name}'." unless @option_data.has_option?(name)
94
+ @option_data[name]
95
+ end
96
+ end
97
+
98
+ #
99
+ # expected_args tells the application how many arguments (not belonging
100
+ # any option) are expected to be seen on the command line
101
+ # The names of the args are used for describing the synopsis (or usage).
102
+ # If there is an indeterminant amount of arguments, they are not
103
+ # named, but returned in an array.
104
+ # expected_args takes either a list of argument names
105
+ #
106
+ # =Usage
107
+ # expected_args :sym1
108
+ # expected_args :sym1, :sym2, ...
109
+ # expected_args n #=> arg_arity => [n,n]
110
+ # expected_args arity
111
+ #
112
+ # =Examples
113
+ #
114
+ # Many forms are valid. Some examples follow:
115
+ # expected_args 0 #=> @args = []; same as not calling expected_args
116
+ # synopsis: Usage: app
117
+
118
+ # expected_args 1 #=> @args is array
119
+ # synopsis: Usage: app arg
120
+
121
+ # expected_args 2 #=> @args is array
122
+ # synopsis: Usage: app arg1 arg2
123
+
124
+ # expected_args 10 #=> @args is array
125
+ # synopsis: Usage: app arg1 ... arg10
126
+
127
+ # expected_args :file #=> @file = <arg>
128
+ # synopsis: Usage: app file
129
+
130
+ # expected_args :file1, :file2 #=> @file1 = <arg1>, @file2 = <arg2>
131
+ # synopsis: Usage: app file1 file2
132
+
133
+ # expected_args [0,1] #=> @args is array
134
+ # synopsis: Usage: app [arg1 [arg2]]
135
+
136
+ # expected_args [2,3] #=> @args is array
137
+ # synopsis: Usage: app arg1 arg2 [arg3]
138
+
139
+ # expected_args [0,-1] #=> @args is array
140
+ # synopsis: Usage: app [arg1 [arg...]]
141
+ #
142
+
143
+ # expected_args :cmd
144
+ # Now, what to do if command line has more args than expected
145
+ # app --app-option cmd --cmd-option arg-for-cmd
146
+ #
147
+ def expected_args(*exp_args)
148
+ @arg_names = []
149
+ case exp_args.size
150
+ when 0 then @arg_arity = [0,0]
151
+ when 1
152
+ case exp_args[0]
153
+ when Fixnum
154
+ v = exp_args[0]
155
+ @arg_arity = [v,v]
156
+ when Symbol
157
+ @arg_names = exp_args
158
+ @arg_arity = [1,1]
159
+ when Array
160
+ v = exp_args[0]
161
+ __validate_arg_arity(v)
162
+ @arg_arity = v
163
+ else
164
+ raise(InvalidArgumentArityError,
165
+ "Args must be a Fixnum or Array: #{exp_args[0].inspect}.")
166
+ end
167
+ else
168
+ @arg_names = exp_args
169
+ size = exp_args.size
170
+ @arg_arity = [size, size]
171
+ end
172
+ end
173
+
174
+ def use_replay(attribs = {})
175
+ @replay = true
176
+ @replay_file = attribs[:replay_file] || @replay_file
177
+ end
178
+
179
+ def usage
180
+ " Usage: #{name} #{synopsis}"
181
+ end
182
+
183
+ def man
184
+ require 'text/format'
185
+ f = Text::Format.new
186
+ f = Text::Format.new
187
+ f.columns = @columns
188
+ f.first_indent = 4
189
+ f.body_indent = @body_indent
190
+ f.tag_paragraph = false
191
+
192
+ s = []
193
+ s << ["NAME\n"]
194
+
195
+ nm = "#{short_description}".empty? ? name : "#{name} - #{short_description}"
196
+ s << f.format(nm)
197
+
198
+ sn = "#{synopsis}".empty? ? "" : "#{name} #{synopsis}"
199
+ unless sn.empty?
200
+ s << "SYNOPSIS\n"
201
+ s << f.format(sn)
202
+ end
203
+
204
+ dc = "#{long_description}"
205
+ unless dc.empty?
206
+ s << "DESCRIPTION\n"
207
+ s << f.format(dc)
208
+ end
209
+
210
+ op = option_parser.to_s
211
+ unless op.empty?
212
+ s << option_parser.to_s
213
+ end
214
+
215
+ ar = "#{author}"
216
+ unless ar.empty?
217
+ s << "AUTHOR: #{ar}"
218
+ end
219
+
220
+
221
+ ct = "COPYRIGHT (c) #{copyright}"
222
+ unless "#{copyright}".empty?
223
+ s << ct
224
+ end
225
+
226
+ s.join("\n")
227
+ end
228
+ alias :help :man
229
+
230
+ def name
231
+ File.basename(pathname)
232
+ end
233
+
234
+ def pathname
235
+ @@appname
236
+ end
237
+
238
+ def get_arg
239
+ CommandLine::OptionParser::GET_ARGS
240
+ end
241
+ alias :get_args :get_arg
242
+
243
+ def append_arg
244
+ CommandLine::OptionParser::GET_ARG_ARRAY
245
+ end
246
+
247
+ def required
248
+ CommandLine::OptionParser::OPT_NOT_FOUND_BUT_REQUIRED
249
+ end
250
+
251
+ def self.run(argv=ARGV)
252
+ # Usurp an existing initialize so ours can be called first.
253
+ # We rename it __child_initialize and call it from initialize.
254
+ if self.private_instance_methods(false).include?("initialize")
255
+ $VERBOSE, verbose = nil, $VERBOSE
256
+ self.class_eval {
257
+ alias :__child_initialize :initialize
258
+ remove_method :initialize
259
+ }
260
+ $VERBOSE = verbose
261
+ end
262
+ obj = self.new
263
+ obj.__parse_command_line(argv)
264
+ obj.main
265
+
266
+ #alias :user_init :initialize
267
+ #@@child_class.new.main if ($0 == @@appname)
268
+ obj
269
+ rescue => err
270
+ puts "ERROR: #{err}"
271
+ exit(-1)
272
+ end
273
+
274
+ def self.inherited(child_class)
275
+ @@appname = caller[0][/.*:/][0..-2]
276
+ @@child_class = child_class
277
+ if @@appname == $0
278
+ __set_auto_run
279
+ end
280
+ end
281
+
282
+ def self.__set_auto_run
283
+ at_exit { @@child_class.run }
284
+ end
285
+
286
+ def main
287
+ #raise(MissingMainError, "Method #main must be defined in class #{@@child_class}.")
288
+ @@child_class.class_eval %{ def main; end }
289
+ #self.class_eval %{ def main; end }
290
+ end
291
+
292
+ def __save_argv
293
+ return unless @replay
294
+
295
+ line = 0
296
+ File.open(@replay_file, "w") { |f|
297
+ @argv.each { |arg|
298
+ f.puts "\n" if arg[0] == ?- && line != 0
299
+ f.print " #{arg}"
300
+ line += 1
301
+ }
302
+ }
303
+ end
304
+
305
+ def __restore_argv
306
+ @argv = File.read(@replay_file).gsub(/\n/, "").split
307
+ raise "Bad @argv" unless @argv.kind_of?(Array)
308
+ end
309
+
310
+ def __parse_command_line(argv)
311
+ @argv = argv
312
+ if @replay && File.exist?(@replay_file) && !@argv.grep("-r").empty?
313
+ __restore_argv
314
+ elsif @argv.empty? && @arg_arity[0] != 0
315
+ puts usage
316
+ exit(0)
317
+ end
318
+
319
+ begin
320
+ @option_data = @option_parser.parse(@argv)
321
+ @args = @option_data.args
322
+ rescue => err
323
+ puts err
324
+ puts
325
+ puts usage
326
+ exit(-1)
327
+ end
328
+
329
+ __validate_args(@option_data.args)
330
+ @arg_names.each_with_index { |name, idx|
331
+ instance_variable_set("@#{name}", @option_data.args[idx])
332
+ }
333
+
334
+ __save_argv
335
+ end
336
+
337
+ def __validate_arg_arity(arity)
338
+ min, max = *arity
339
+ raise(InvalidArgumentArityError, "Minimum argument arity '#{min}' must be "+
340
+ "greater than or equal to 0.") unless min >= 0
341
+ raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
342
+ "greater than or equal to -1.") if max < -1
343
+ raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
344
+ "greater than minimum arg_arity '#{min}'.") if max < min && max != -1
345
+ end
346
+
347
+ def __initialize_text_formatting
348
+ #
349
+ # Formatting defaults
350
+ #
351
+ console_width = ENV["COLUMNS"]
352
+ @columns =
353
+ if console_width.nil?
354
+ DEFAULT_CONSOLE_WIDTH
355
+ elsif console_width < MIN_CONSOLE_WIDTH
356
+ console_width
357
+ else
358
+ console_width - DEFAULT_BODY_INDENT
359
+ end
360
+ @body_indent = DEFAULT_BODY_INDENT
361
+ @tag_paragraph = false
362
+ @order = :index # | :alpha
363
+ end
364
+
365
+ def __validate_args(od_args)
366
+ size = od_args.size
367
+ min, max = @arg_arity
368
+ max = 1.0/0.0 if -1 == max
369
+ raise(ArgumentError,
370
+ "Missing expected arguments. Found #{size} but expected #{min}. "+
371
+ "#{od_args.inspect}\n"+
372
+ "#{usage}") if size < min
373
+ raise(ArgumentError, "Too many arguments. Found #{size} but "+
374
+ "expected #{max}.\n#{usage}") if size > max
375
+ end
376
+
377
+ def __help
378
+ {
379
+ :names => %w(--help -h),
380
+ :arity => [0,0],
381
+ :opt_description => "Displays help page.",
382
+ :arg_description => "",
383
+ :opt_found => lambda { puts man; exit },
384
+ :opt_not_found => false
385
+ }
386
+ end
387
+
388
+ def __verbose
389
+ {
390
+ :names => %w(--verbose -v),
391
+ :arity => [0,0],
392
+ :opt_description => "Sets verbosity level. Subsequent "+
393
+ "flags increase verbosity level",
394
+ :arg_description => "",
395
+ :opt_found => lambda { @verbose ||= -1; @verbose += 1 },
396
+ :opt_not_found => nil
397
+ }
398
+ end
399
+
400
+ def __version
401
+ {
402
+ :names => %w(--version -V),
403
+ :arity => [0,0],
404
+ :opt_description => "Displays application version.",
405
+ :arg_description => "",
406
+ :opt_found => lambda {
407
+ begin
408
+ puts "#{name} - Version: #{version}"
409
+ rescue
410
+ puts "No version specified"
411
+ end;
412
+ exit
413
+ },
414
+ :opt_not_found => nil
415
+ }
416
+ end
417
+
418
+ def __debug
419
+ {
420
+ :names => %w(--debug -d),
421
+ :arity => [0,0],
422
+ :opt_description => "Sets debug to true.",
423
+ :arg_description => "",
424
+ :opt_found => lambda { $DEBUG = true }
425
+ }
426
+ end
427
+ end#class Application
428
+
429
+ Application_wo_AutoRun = Class.new(Application)
430
+ class Application_wo_AutoRun
431
+ def self.inherited(child_class)
432
+ @@appname = caller[0][/.*:/][0..-2]
433
+ @@child_class = child_class
434
+ end
435
+ end
436
+
437
+ end#module CommandLine