CommandLine 0.6.0 → 0.7.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.
@@ -33,25 +33,30 @@ class Application
33
33
  MIN_CONSOLE_WIDTH = 10
34
34
  DEFAULT_BODY_INDENT = 4
35
35
 
36
- #def options
37
- # raise(OptionError,
38
- # "Options must be over-written with a valid (or empty) options list.")
39
- #end
40
-
41
36
  def initialize
42
- # Ensure initializations have taken place
43
- @arg_arity ||= [0,0]
44
- @options ||= []
45
- @arg_names ||= []
46
- @option_parser ||= CommandLine::OptionParser.new(@options)
37
+
38
+ @synopsis = ""
39
+ @arg_arity = [0,0]
40
+ @options = []
41
+ @arg_names = []
42
+ @args = []
43
+ @argv ||= ARGV
44
+
47
45
  _init_format
48
46
 
49
- if ARGV.empty? && [0,0] != @arg_arity
47
+ __child_initialize if
48
+ self.class.private_instance_methods(false).include?("__child_initialize")
49
+
50
+ @option_parser ||= CommandLine::OptionParser.new(@options)
51
+ end
52
+
53
+ def parse_command_line(argv)
54
+ if argv.empty? && [0,0] != @arg_arity
50
55
  puts usage
51
56
  exit(0)
52
57
  end
53
58
 
54
- @option_data = @option_parser.parse
59
+ @option_data = @option_parser.parse(argv)
55
60
 
56
61
  validate_args(@option_data.args)
57
62
  @arg_names.each_with_index { |name, idx|
@@ -88,6 +93,10 @@ class Application
88
93
  "expected #{max}.\n#{usage}") if size > max
89
94
  end
90
95
 
96
+ def options(*opts)
97
+ opts.each { |opt| option(*[opt].flatten) }
98
+ end
99
+
91
100
  def option(*args)
92
101
  @options ||= []
93
102
  new_list = []
@@ -106,43 +115,55 @@ class Application
106
115
  end
107
116
 
108
117
  #
109
- # Args tells the application how many arguments (not belonging
118
+ # expected_args tells the application how many arguments (not belonging
110
119
  # any option) are expected to be seen on the command line
111
120
  # The names of the args are used for describing the synopsis (or usage).
112
121
  # If there is an indeterminant amount of arguments, they are not
113
122
  # named, but returned in an array.
123
+ # expected_args takes either a list of argument names
124
+ #
125
+ # =Usage
126
+ # expected_args :sym1
127
+ # expected_args :sym1, :sym2, ...
128
+ # expected_args n #=> arg_arity => [n,n]
129
+ # expected_args arity
130
+ #
131
+ # =Examples
132
+ #
114
133
  # Many forms are valid. Some examples follow:
115
- # args 0
116
- # synopsis: Usage: app
117
-
118
- # args :none
134
+ # expected_args 0 #=> @args = []; same as not calling expected_args
119
135
  # synopsis: Usage: app
120
136
 
121
- # args 1 #=> args is array
137
+ # expected_args 1 #=> @args is array
122
138
  # synopsis: Usage: app arg
123
139
 
124
- # args 2 #=> args is array
140
+ # expected_args 2 #=> @args is array
125
141
  # synopsis: Usage: app arg1 arg2
126
142
 
127
- # args 10 #=> args is array
143
+ # expected_args 10 #=> @args is array
128
144
  # synopsis: Usage: app arg1 ... arg10
129
145
 
130
- # args :file #=> @file = <arg>
146
+ # expected_args :file #=> @file = <arg>
131
147
  # synopsis: Usage: app file
132
148
 
133
- # args :file1, :file2 #=> @file1 = <arg1>, @file2 = <arg2>
149
+ # expected_args :file1, :file2 #=> @file1 = <arg1>, @file2 = <arg2>
134
150
  # synopsis: Usage: app file1 file2
135
151
 
136
- # args [0,1] #=> args is array
137
- # synopsis: Usage: app [arg [arg]]
152
+ # expected_args [0,1] #=> @args is array
153
+ # synopsis: Usage: app [arg1 [arg2]]
138
154
 
139
- # args [2,3] #=> args is array
140
- # synopsis: Usage: app arg[2,3]
155
+ # expected_args [2,3] #=> @args is array
156
+ # synopsis: Usage: app arg1 arg2 [arg3]
141
157
 
142
- # args [0,-1] #=> args is array
143
- # synopsis: Usage: app [arg [arg...]]
158
+ # expected_args [0,-1] #=> @args is array
159
+ # synopsis: Usage: app [arg1 [arg...]]
144
160
  #
145
- def args(*expected_args)
161
+
162
+ # expected_args :cmd
163
+ # Now, what to do if command line has more args than expected
164
+ # app --app-option cmd --cmd-option arg-for-cmd
165
+ #
166
+ def expected_args(*expected_args)
146
167
  @arg_names = []
147
168
  case expected_args.size
148
169
  when 0 then @arg_arity = [0,0]
@@ -247,28 +268,45 @@ class Application
247
268
  CommandLine::OptionParser::GET_ARG_ARRAY
248
269
  end
249
270
 
250
- def self.run
251
- @@app.new.main if ($0 == @@appname)
271
+ def self.run(argv=ARGV)
272
+ if self.private_instance_methods(false).include?("initialize")
273
+ $VERBOSE, verbose = nil, $VERBOSE
274
+ self.class_eval {
275
+ alias :__child_initialize :initialize
276
+ remove_method :initialize
277
+ }
278
+ $VERBOSE = verbose
279
+ end
280
+ obj = self.new
281
+ obj.parse_command_line(argv)
282
+ obj.main
283
+
284
+ #alias :user_init :initialize
285
+ #@@child_class.new.main if ($0 == @@appname)
286
+ obj
252
287
  rescue => err
253
288
  puts "ERROR: #{err}"
254
289
  exit(-1)
255
290
  end
256
291
 
257
- def self.inherited(klass)
292
+ def self.inherited(child_class)
258
293
  @@appname = caller[0][/.*:/][0..-2]
259
- @@app = klass
260
- at_exit { @@app.run }
294
+ @@child_class = child_class
295
+ if @@appname == $0
296
+ at_exit { @@child_class.run }
297
+ end
261
298
  end
262
299
 
263
300
  def main
264
- #raise(MissingMainError, "Method #main must be defined in class #{@@app}.")
265
- @@app.class_eval %{ def main; end }
301
+ #raise(MissingMainError, "Method #main must be defined in class #{@@child_class}.")
302
+ @@child_class.class_eval %{ def main; end }
303
+ #self.class_eval %{ def main; end }
266
304
  end
267
305
 
268
306
  def _help
269
307
  {
270
308
  :names => %w(--help -h),
271
- :arg_arity => [0,0],
309
+ :arity => [0,0],
272
310
  :opt_description => "Displays help page.",
273
311
  :arg_description => "",
274
312
  :opt_found => lambda { puts man; exit },
@@ -279,7 +317,7 @@ class Application
279
317
  def _verbose
280
318
  {
281
319
  :names => %w(--verbose -v),
282
- :arg_arity => [0,0],
320
+ :arity => [0,0],
283
321
  :opt_description => "Sets verbosity level. Subsequent "+
284
322
  "flags increase verbosity level",
285
323
  :arg_description => "",
@@ -291,7 +329,7 @@ class Application
291
329
  def _version
292
330
  {
293
331
  :names => %w(--version -V),
294
- :arg_arity => [0,0],
332
+ :arity => [0,0],
295
333
  :opt_description => "Displays application version.",
296
334
  :arg_description => "",
297
335
  :opt_found => lambda {
@@ -309,7 +347,7 @@ class Application
309
347
  def _debug
310
348
  {
311
349
  :names => %w(--debug -d),
312
- :arg_arity => [0,0],
350
+ :arity => [0,0],
313
351
  :opt_description => "Sets debug to true.",
314
352
  :arg_description => "",
315
353
  :opt_found => lambda { $DEBUG = true }
@@ -36,12 +36,12 @@ class Option
36
36
  # need to change this to support - and --
37
37
  NON_POSIX_OPTION_RE = /^(-|-{1,2}[a-zA-Z_]+[-_a-zA-Z0-9]*)/
38
38
 
39
- PROPERTIES = [ :arg_arity, :opt_description, :arg_description,
39
+ PROPERTIES = [ :arity, :opt_description, :arg_description,
40
40
  :opt_found, :opt_not_found, :posix
41
41
  ]
42
42
 
43
43
  FLAG_BASE_OPTS = {
44
- :arg_arity => [0,0],
44
+ :arity => [0,0],
45
45
  # :opt_description => nil,
46
46
  :arg_description => "",
47
47
  :opt_found => true,
@@ -50,7 +50,7 @@ class Option
50
50
 
51
51
  # You get these without asking for them
52
52
  DEFAULT_OPTS = {
53
- :arg_arity => [1,1],
53
+ :arity => [1,1],
54
54
  :opt_description => "",
55
55
  :arg_description => "",
56
56
  :opt_found => true,
@@ -77,6 +77,7 @@ class Option
77
77
  end
78
78
  end
79
79
 
80
+ @flag = nil unless defined?(@flag)
80
81
  type = @flag.nil? ? :default : :flag
81
82
  merge_hash =
82
83
  case type
@@ -84,7 +85,7 @@ class Option
84
85
  when :default then DEFAULT_OPTS
85
86
  else raise(InvalidConstructionError,
86
87
  "Invalid arguments to Option.new. Must be a property hash with "+
87
- "keys [:names, :arg_arity, :opt_description, :arg_description, "+
88
+ "keys [:names, :arity, :opt_description, :arg_description, "+
88
89
  ":opt_found, :opt_not_found] or "+
89
90
  "an option type [:flag, :default].")
90
91
  end
@@ -102,17 +103,17 @@ class Option
102
103
  @properties[:names] = [@properties[:names]] unless
103
104
  @properties[:names].kind_of?(Array)
104
105
 
105
- arg_arity = @properties[:arg_arity]
106
- @properties[:arg_arity] = [arg_arity, arg_arity] unless
106
+ arg_arity = @properties[:arity]
107
+ @properties[:arity] = [arg_arity, arg_arity] unless
107
108
  arg_arity.kind_of?(Array)
108
109
 
109
- raise "Invalid value for arg_arity '#{arg_arity}'." unless
110
+ raise "Invalid value for arity '#{arg_arity}'." unless
110
111
  arg_arity.kind_of?(Array) || arg_arity.kind_of?(Fixnum)
111
112
 
112
113
  raise(InvalidArgumentArityError,
113
114
  "Conflicting value given to new option: :flag "+
114
- "and :arg_arity = #{@properties[:arg_arity].inspect}.") if
115
- :flag == type && [0,0] != @properties[:arg_arity]
115
+ "and :arity = #{@properties[:arity].inspect}.") if
116
+ :flag == type && [0,0] != @properties[:arity]
116
117
 
117
118
  names = @properties[:names]
118
119
  raise(MissingOptionNameError,
@@ -120,7 +121,7 @@ class Option
120
121
  names.nil? || names.empty?
121
122
 
122
123
  names.each { |name| check_option_name(name) }
123
- validate_arity @properties[:arg_arity]
124
+ validate_arity @properties[:arity]
124
125
 
125
126
  create_opt_description if :flag == type
126
127
  end
@@ -149,7 +150,7 @@ class Option
149
150
  end
150
151
 
151
152
  def validate_arity(arity)
152
- raise ":arg_arity is nil" if arity.nil?
153
+ raise ":arity is nil" if arity.nil?
153
154
  min, max = *arity
154
155
 
155
156
  raise(InvalidArgumentArityError, "Minimum argument arity '#{min}' must be "+
@@ -157,9 +158,9 @@ class Option
157
158
  raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
158
159
  "greater than or equal to -1.") if max < -1
159
160
  raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
160
- "greater than minimum arg_arity '#{min}'.") if max < min && max != -1
161
+ "greater than minimum arity '#{min}'.") if max < min && max != -1
161
162
  if @posix
162
- raise(InvalidArgumentArityError, "Posix options only support :arg_arity "+
163
+ raise(InvalidArgumentArityError, "Posix options only support :arity "+
163
164
  "of [0,0] or [1,1].") unless ([0,0] == arity) || ([1,1] == arity)
164
165
  end
165
166
  end
@@ -142,10 +142,10 @@ class OptionParser
142
142
  # :
143
143
  #
144
144
  # add_option :names => %w(--version -v),
145
- # :arg_arity => [0,0], # default
145
+ # :arity => [0,0], # default
146
146
  # :option_description => "Returns Version"
147
147
  # add_option :names => %w(--file -f),
148
- # :arg_arity => [1,:unlimited],
148
+ # :arity => [1,:unlimited],
149
149
  # :opt_description => "Define the output filename.",
150
150
  # :arg_description => "Output file"
151
151
  # :opt_exists => lambda {}
@@ -276,13 +276,13 @@ raise "Wrong data type '#{option.name}." unless Option === option
276
276
  end
277
277
 
278
278
  def get_opt_args(opt, user_option, args)
279
- min, max = *opt.arg_arity
279
+ min, max = *opt.arity
280
280
  size = args.size
281
281
 
282
282
  if (min == max && max > 0 && size < max) || (size < min)
283
283
  raise(MissingRequiredOptionArgumentError,
284
284
  "Insufficient arguments #{args.inspect}for option '#{user_option}' "+
285
- "with :arg_arity #{opt.arg_arity.inspect}")
285
+ "with :arity #{opt.arity.inspect}")
286
286
  end
287
287
 
288
288
  if 0 == min && 0 == max
@@ -297,7 +297,7 @@ raise "Wrong data type '#{option.name}." unless Option === option
297
297
  flags = []
298
298
  nflags = []
299
299
  @options.each { |o|
300
- if [0,0] == o.arg_arity
300
+ if [0,0] == o.arity
301
301
  flags << o.names[0][1..1]
302
302
  else
303
303
  nflags << o.names[0][1..1]
@@ -457,7 +457,7 @@ end
457
457
  def to_s(sep="\n")
458
458
  return "" if @options.empty?
459
459
 
460
- require 'commandline/text/format'
460
+ require 'text/format'
461
461
  @f = Text::Format.new
462
462
  @f.columns = @columns
463
463
  @f.first_indent = 4
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
3
3
  specification_version: 1
4
4
  name: CommandLine
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.6.0
7
- date: 2005-06-24
6
+ version: 0.7.0
7
+ date: 2005-07-13
8
8
  summary: Tools to facilitate creation of command line applications and flexible parsing of command line options.
9
9
  require_paths:
10
10
  - lib
@@ -36,12 +36,10 @@ files:
36
36
  - lib/commandline/application.rb
37
37
  - lib/commandline/optionparser
38
38
  - lib/commandline/optionparser.rb
39
- - lib/commandline/text
40
39
  - lib/commandline/utils.rb
41
40
  - lib/commandline/optionparser/option.rb
42
41
  - lib/commandline/optionparser/optiondata.rb
43
42
  - lib/commandline/optionparser/optionparser.rb
44
- - lib/commandline/text/format.rb
45
43
  - lib/test/unit
46
44
  - lib/test/unit/systemtest.rb
47
45
  - README
@@ -54,4 +52,14 @@ extra_rdoc_files:
54
52
  executables: []
55
53
  extensions: []
56
54
  requirements: []
57
- dependencies: []
55
+ dependencies:
56
+ - !ruby/object:Gem::Dependency
57
+ name: text-format
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Version::Requirement
60
+ requirements:
61
+ -
62
+ - "="
63
+ - !ruby/object:Gem::Version
64
+ version: 1.0.0
65
+ version: