commandline 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
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