main 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,138 @@
1
+ module Main
2
+ class Usage < ::Array
3
+ attribute 'chunkname'
4
+ attribute 'upcase'
5
+ attribute 'eos'
6
+
7
+ def initialize opts={}
8
+ self.fields=[]
9
+ self.chunkname = lambda{|chunkname| chunkname.to_s.strip.upcase}
10
+ self.upcase = true
11
+ self.eos = "\n\n"
12
+ if opts.has_key?(:upcase) or opts.has_key?('upcase')
13
+ self.upcase = opts[:upcase] || opts['optcase']
14
+ end
15
+ end
16
+
17
+ def clear
18
+ super
19
+ ensure
20
+ fields.clear
21
+ end
22
+
23
+ def delete_at key
24
+ self[key] = nil
25
+ end
26
+ alias_method 'delete', 'delete_at'
27
+
28
+ def self.default_synopsis main
29
+ s = "#{ main.name }"
30
+
31
+ main.parameters.each do |p|
32
+ if p.type == :argument
33
+ if p.required?
34
+ s << " #{ p.name }"
35
+ else
36
+ s << " [#{ p.name }]"
37
+ end
38
+ end
39
+ end
40
+
41
+ main.parameters.each do |p|
42
+ if p.type == :keyword
43
+ if p.required?
44
+ s << " #{ p.name }=#{ p.name }"
45
+ else
46
+ s << " [#{ p.name }=#{ p.name }]"
47
+ end
48
+ end
49
+ end
50
+
51
+ n = 0
52
+ main.parameters.each do |p|
53
+ if p.type == :option
54
+ if p.required?
55
+ case p.argument
56
+ when :required
57
+ s << " --#{ p.name }=#{ p.name }"
58
+ when :optional
59
+ s << " --#{ p.name }=[#{ p.name }]"
60
+ else
61
+ s << " --#{ p.name }"
62
+ end
63
+ else
64
+ n += 1
65
+ end
66
+ end
67
+ end
68
+ if n > 0
69
+ s << " [options]+"
70
+ end
71
+
72
+ s
73
+ end
74
+
75
+ def self.default_usage main
76
+ usage = new
77
+
78
+ # name
79
+ usage['name'] =
80
+ if main.version?
81
+ "#{ main.name } v#{ main.version }"
82
+ else
83
+ "#{ main.name }"
84
+ end
85
+
86
+ # synopsis
87
+ usage['synopsis'] = main.synopsis
88
+
89
+ # description
90
+ usage['description'] = main.description if main.description?
91
+
92
+ # parameters
93
+ arguments = main.parameters.select{|p| p.type == :argument}
94
+ keywords = main.parameters.select{|p| p.type == :keyword}
95
+ options = main.parameters.select{|p| p.type == :option}
96
+ environment = main.parameters.select{|p| p.type == :environment}
97
+
98
+ help, nothelp = options.partition{|p| p.name == 'help'}
99
+ options = nothelp + help
100
+
101
+ parameters = arguments + keywords + options + environment
102
+
103
+ s =
104
+ parameters.map do |p|
105
+ ps = ''
106
+ ps << Util.columnize("* #{ p.synopsis }", :indent => 2, :width => 78)
107
+ ps << "\n"
108
+ if p.description?
109
+ ps << Util.columnize(p.description, :indent => 6, :width => 78)
110
+ ps << "\n"
111
+ end
112
+ ps
113
+ end.join("\n")
114
+ usage['parameters'] = s
115
+
116
+ # author
117
+ usage['author'] = main.author if main.author?
118
+
119
+ usage
120
+ end
121
+ class << self
122
+ alias_method "default", "default_usage"
123
+ end
124
+
125
+ def to_s
126
+ s = ''
127
+ each_pair do |key, value|
128
+ up, down = key.to_s.upcase, key.to_s.downcase
129
+ if value
130
+ s << (upcase ? up : down) << "\n"
131
+ s << Util.indent(Util.unindent(value.to_s), 2)
132
+ s << eos
133
+ end
134
+ end
135
+ s
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,91 @@
1
+ module Main
2
+ module Util
3
+ module ClassMethods
4
+ end
5
+
6
+ module InstanceMethods
7
+ end
8
+
9
+ module Methods
10
+ def mcp obj
11
+ Marshal.load(Marshal.dump(obj))
12
+ end
13
+
14
+ def indent chunk, n = 2
15
+ lines = chunk.split %r/\n/
16
+ re = nil
17
+ s = ' ' * n
18
+ lines.map! do |line|
19
+ unless re
20
+ margin = line[%r/^\s*/]
21
+ re = %r/^#{ margin }/
22
+ end
23
+ line.gsub re, s
24
+ end.join("\n")
25
+ end
26
+
27
+ def unindent chunk
28
+ lines = chunk.split %r/\n/
29
+ indent = nil
30
+ re = %r/^/
31
+ lines.map! do |line|
32
+ unless indent
33
+ indent = line[%r/^\s*/]
34
+ re = %r/^#{ indent }/
35
+ end
36
+ line.gsub re, ''
37
+ end.join("\n")
38
+ end
39
+
40
+ def columnize buf, opts = {}
41
+ width = Util.getopt 'width', opts, 80
42
+ indent = Util.getopt 'indent', opts
43
+ indent = Fixnum === indent ? (' ' * indent) : "#{ indent }"
44
+ column = []
45
+ words = buf.split %r/\s+/o
46
+ row = "#{ indent }"
47
+ while((word = words.shift))
48
+ if((row.size + word.size) < (width - 1))
49
+ row << word
50
+ else
51
+ column << row
52
+ row = "#{ indent }"
53
+ row << word
54
+ end
55
+ row << ' ' unless row.size == (width - 1)
56
+ end
57
+ column << row unless row.strip.empty?
58
+ column.join "\n"
59
+ end
60
+
61
+ def getopt opt, hash, default = nil
62
+ keys = opt.respond_to?('each') ? opt : [opt]
63
+
64
+ keys.each do |key|
65
+ return hash[key] if hash.has_key? key
66
+ key = "#{ key }"
67
+ return hash[key] if hash.has_key? key
68
+ key = key.intern
69
+ return hash[key] if hash.has_key? key
70
+ end
71
+
72
+ return default
73
+ end
74
+ end
75
+
76
+ BLESS = lambda do |other|
77
+ other.module_eval{
78
+ include Methods
79
+ include InstanceMethods
80
+ extend Methods
81
+ extend ClassMethods
82
+ }
83
+ end
84
+
85
+ def self.included other
86
+ BLESS[ other ]
87
+ end
88
+
89
+ BLESS[ self ]
90
+ end
91
+ end
File without changes
@@ -0,0 +1,17 @@
1
+ require 'main'
2
+
3
+ ARGV.replace %w( 42 ) if ARGV.empty?
4
+
5
+ Main {
6
+ argument('foo'){
7
+ required # this is the default
8
+ cast :int # value cast to Fixnum
9
+ validate{|foo| foo == 42} # raises error in failure case
10
+ description 'the foo param' # shown in --help
11
+ }
12
+
13
+ def run
14
+ p params['foo'].given?
15
+ p params['foo'].value
16
+ end
17
+ }
@@ -0,0 +1,17 @@
1
+ require 'main'
2
+
3
+ ARGV.replace %w( 40 1 1 ) if ARGV.empty?
4
+
5
+ Main {
6
+ argument('foo'){
7
+ arity 3 # foo will given three times
8
+ cast :int # value cast to Fixnum
9
+ validate{|foo| [40,1].include? foo} # raises error in failure case
10
+ description 'the foo param' # shown in --help
11
+ }
12
+
13
+ def run
14
+ p params['foo'].given?
15
+ p params['foo'].values
16
+ end
17
+ }
@@ -0,0 +1,21 @@
1
+ require 'main'
2
+
3
+ ARGV.replace %w( foo=40 foo=2 bar=false ) if ARGV.empty?
4
+
5
+ Main {
6
+ keyword('foo'){
7
+ required # by default keywords are not required
8
+ arity 2
9
+ cast :float
10
+ }
11
+ keyword('bar'){
12
+ cast :bool
13
+ }
14
+
15
+ def run
16
+ p params['foo'].given?
17
+ p params['foo'].values
18
+ p params['bar'].given?
19
+ p params['bar'].value
20
+ end
21
+ }
@@ -0,0 +1,26 @@
1
+ require 'main'
2
+
3
+ ARGV.replace %w( --foo=40 -f2 ) if ARGV.empty?
4
+
5
+ Main {
6
+ option('foo', 'f'){
7
+ required # by default options are not required, we could use 'foo=foo'
8
+ # above as a shortcut
9
+ argument_required
10
+ arity 2
11
+ cast :float
12
+ }
13
+
14
+ option('bar=[bar]', 'b'){ # note shortcut syntax for optional args
15
+ # argument_optional # we could also use this method
16
+ cast :bool
17
+ default false
18
+ }
19
+
20
+ def run
21
+ p params['foo'].given?
22
+ p params['foo'].values
23
+ p params['bar'].given?
24
+ p params['bar'].value
25
+ end
26
+ }
@@ -0,0 +1,523 @@
1
+ $:.unshift '.'
2
+ $:.unshift './lib'
3
+ $:.unshift '..'
4
+ $:.unshift '../lib'
5
+
6
+ require 'stringio'
7
+ require 'test/unit'
8
+ require 'main'
9
+
10
+ class T < Test::Unit::TestCase
11
+ attr 'status'
12
+
13
+ def setup
14
+ @status = nil
15
+ @logger = Logger.new StringIO.new
16
+ @error = nil
17
+ end
18
+
19
+ def teardown
20
+ end
21
+
22
+ def main argv=[], env={}, &b
23
+ at_exit{ exit! }
24
+ $VERBOSE=nil
25
+ ARGV.replace argv
26
+ ENV.clear
27
+ env.each{|k,v| ENV[k.to_s]=v.to_s}
28
+ main = nil
29
+ begin
30
+ main = Object::Main.new(&b)
31
+ main.logger = @logger
32
+ main.__run__
33
+ rescue Exception => e
34
+ if SystemExit === e
35
+ @status = e.status
36
+ else
37
+ raise
38
+ end
39
+ end
40
+ main
41
+ end
42
+
43
+ #
44
+ # basic test
45
+ #
46
+ def test_0000
47
+ assert_nothing_raised{
48
+ main{
49
+ def run() end
50
+ }
51
+ }
52
+ end
53
+ def test_0010
54
+ x = nil
55
+ assert_nothing_raised{
56
+ main{
57
+ define_method(:run){ x = 42 }
58
+ }
59
+ }
60
+ assert x == 42
61
+ end
62
+ #
63
+ # exit status
64
+ #
65
+ def test_0020
66
+ assert_nothing_raised{
67
+ main{
68
+ def run() end
69
+ }
70
+ }
71
+ assert status == 0
72
+ end
73
+ def test_0030
74
+ assert_nothing_raised{
75
+ main{
76
+ def run() exit 42 end
77
+ }
78
+ }
79
+ assert status == 42
80
+ end
81
+ def test_0040
82
+ assert_nothing_raised{
83
+ fork{
84
+ main{
85
+ def run() exit! 42 end
86
+ }
87
+ }
88
+ Process.wait
89
+ assert $?.exitstatus == 42
90
+ }
91
+ end
92
+ def test_0050
93
+ assert_nothing_raised{
94
+ main{
95
+ def run() raise end
96
+ }
97
+ }
98
+ assert status == 1
99
+ end
100
+ def test_0060
101
+ assert_nothing_raised{
102
+ main{
103
+ def run() raise ArgumentError end
104
+ }
105
+ }
106
+ assert status == 1
107
+ end
108
+ def test_0060
109
+ assert_nothing_raised{
110
+ main{
111
+ def run() exit_status 42; raise end
112
+ }
113
+ }
114
+ assert status == 42
115
+ end
116
+ def test_0070
117
+ assert_nothing_raised{
118
+ main{
119
+ def run() exit_status 42; raise ArgumentError end
120
+ }
121
+ }
122
+ assert status == 42
123
+ end
124
+ #
125
+ # parameter parsing
126
+ #
127
+ def test_0080
128
+ p = nil
129
+ argv = %w[ 42 ]
130
+ assert_nothing_raised{
131
+ main(argv){
132
+ parameter('foo'){ type :argument }
133
+ define_method('run'){ p = param['foo'] }
134
+ }
135
+ }
136
+ assert p.value == argv.first
137
+ assert p.values == argv
138
+ end
139
+ def test_0080
140
+ p = nil
141
+ assert_raises(Main::Parameter::NotGiven){
142
+ main(){
143
+ argument 'foo'
144
+ define_method('run'){ }
145
+ }
146
+ }
147
+ end
148
+ def test_0090
149
+ p = nil
150
+ argv = %w[ 42 ]
151
+ given = nil
152
+ assert_nothing_raised{
153
+ main(argv){
154
+ argument 'foo'
155
+ define_method('run'){ p = param['foo'] }
156
+ }
157
+ }
158
+ assert p.value == argv.first
159
+ assert p.values == argv
160
+ assert p.given?
161
+ end
162
+ def test_0100
163
+ p = nil
164
+ argv = %w[]
165
+ given = nil
166
+ assert_nothing_raised{
167
+ main(argv){
168
+ p = argument('foo'){ optional }
169
+ define_method('run'){ p = param['foo'] }
170
+ }
171
+ }
172
+ assert p.optional?
173
+ assert !p.required?
174
+ assert p.value == nil
175
+ assert p.values == []
176
+ assert !p.given?
177
+ end
178
+ def test_0101
179
+ p = nil
180
+ argv = %w[]
181
+ given = nil
182
+ assert_nothing_raised{
183
+ main(argv){
184
+ p = argument('foo'){ required false }
185
+ define_method('run'){ p = param['foo'] }
186
+ }
187
+ }
188
+ assert p.optional?
189
+ assert !p.required?
190
+ assert p.value == nil
191
+ assert p.values == []
192
+ assert !p.given?
193
+ end
194
+ def test_0110
195
+ p = nil
196
+ argv = %w[ --foo ]
197
+ assert_nothing_raised{
198
+ main(argv){
199
+ option('foo'){ required }
200
+ define_method('run'){ p = param['foo'] }
201
+ }
202
+ }
203
+ assert p.value == true
204
+ assert p.values ==[true]
205
+ assert p.given?
206
+ end
207
+ def test_0120
208
+ p = nil
209
+ argv = []
210
+ assert_nothing_raised{
211
+ main(argv){
212
+ option 'foo'
213
+ define_method('run'){ p = param['foo'] }
214
+ }
215
+ }
216
+ assert p.value == nil
217
+ assert p.values == []
218
+ assert !p.given?
219
+ end
220
+ def test_0130
221
+ p = nil
222
+ assert_nothing_raised{
223
+ main(%w[--foo=42]){
224
+ option('foo'){ required; argument_required }
225
+ define_method('run'){ p = param['foo']}
226
+ }
227
+ }
228
+ assert p.required?
229
+ assert p.argument_required?
230
+ assert !p.optional?
231
+ end
232
+ def test_0131
233
+ assert_raises(Main::Parameter::NotGiven){
234
+ main(){
235
+ option('foo'){ required; argument_required }
236
+ define_method('run'){}
237
+ }
238
+ }
239
+ end
240
+ def test_0140
241
+ assert_raises(Main::Parameter::MissingArgument){
242
+ main(['--foo']){
243
+ option('foo'){ required; argument_required }
244
+ define_method('run'){}
245
+ }
246
+ }
247
+ end
248
+ def test_0150
249
+ param = nil
250
+ assert_nothing_raised{
251
+ main(%w[--foo=42 --bar=42.0 --foobar=true --barfoo=false --uri=http://foo --x=s]){
252
+ option('foo'){
253
+ required
254
+ argument_required
255
+ cast :int
256
+ }
257
+ option('bar'){
258
+ argument_required
259
+ cast :float
260
+ }
261
+ option('foobar'){
262
+ argument_required
263
+ cast :bool
264
+ }
265
+ option('barfoo'){
266
+ argument_required
267
+ cast :string
268
+ }
269
+ option('uri'){
270
+ argument_required
271
+ cast :uri
272
+ }
273
+ option('x'){
274
+ argument_required
275
+ cast{|x| x.to_s.upcase}
276
+ }
277
+ define_method('run'){ param = params }
278
+ }
279
+ }
280
+ assert param['foo'].value == 42
281
+ assert param['bar'].value == 42.0
282
+ assert param['foobar'].value == true
283
+ assert param['barfoo'].value == 'false'
284
+ assert param['uri'].value == URI.parse('http://foo')
285
+ assert param['x'].value == 'S'
286
+ end
287
+ def test_0160
288
+ p = nil
289
+ assert_nothing_raised{
290
+ main(%w[--foo=42]){
291
+ option('foo'){
292
+ required
293
+ argument_required
294
+ cast :int
295
+ validate{|x| x == 42}
296
+ }
297
+ define_method('run'){ p = param['foo']}
298
+ }
299
+ }
300
+ assert p.value == 42
301
+ assert p.required?
302
+ assert p.argument_required?
303
+ assert !p.optional?
304
+ end
305
+ def test_0170
306
+ assert_raises(Main::Parameter::InValid){
307
+ main(%w[--foo=40]){
308
+ option('foo'){
309
+ required
310
+ argument_required
311
+ cast :int
312
+ validate{|x| x == 42}
313
+ }
314
+ define_method('run'){ }
315
+ }
316
+ }
317
+ end
318
+ def test_0180
319
+ assert_nothing_raised{
320
+ main(%w[--foo=42]){
321
+ option('--foo=foo'){
322
+ required
323
+ # argument_required
324
+ cast :int
325
+ validate{|x| x == 42}
326
+ }
327
+ define_method('run'){ }
328
+ }
329
+ }
330
+ end
331
+ def test_0190
332
+ assert_raises(Main::Parameter::MissingArgument){
333
+ main(%w[--foo]){
334
+ option('--foo=foo'){ }
335
+ define_method('run'){ }
336
+ }
337
+ }
338
+ end
339
+ def test_0200
340
+ p = nil
341
+ assert_nothing_raised{
342
+ main(%w[--foo]){
343
+ option('--foo=[foo]'){ }
344
+ define_method('run'){ p = param['foo'] }
345
+ }
346
+ }
347
+ assert p.value == true
348
+ end
349
+ def test_0210
350
+ p = nil
351
+ assert_nothing_raised{
352
+ main(%w[--foo=42]){
353
+ option('--foo=[foo]'){
354
+ cast :int
355
+ validate{|x| x == 42}
356
+ }
357
+ define_method('run'){ p = param['foo'] }
358
+ }
359
+ }
360
+ assert p.value == 42
361
+ end
362
+ def test_0220
363
+ p = nil
364
+ assert_nothing_raised{
365
+ main(%w[--foo=40 --foo=2]){
366
+ option('--foo=foo'){
367
+ arity 2
368
+ cast :int
369
+ validate{|x| x == 40 or x == 2}
370
+ }
371
+ define_method('run'){ p = param['foo'] }
372
+ }
373
+ }
374
+ assert p.value == 40
375
+ assert p.values == [40,2]
376
+ end
377
+ def test_0230
378
+ p = nil
379
+ assert_nothing_raised{
380
+ main(%w[foo=42]){
381
+ keyword('foo'){
382
+ cast :int
383
+ validate{|x| x == 42}
384
+ }
385
+ define_method('run'){ p = param['foo'] }
386
+ }
387
+ }
388
+ assert p.value == 42
389
+ end
390
+ def test_0240
391
+ foo = nil
392
+ bar = nil
393
+ assert_nothing_raised{
394
+ main(%w[foo= bar]){
395
+ keyword 'foo'
396
+ keyword 'bar'
397
+ define_method('run'){
398
+ foo = param['foo']
399
+ bar = param['bar']
400
+ }
401
+ }
402
+ }
403
+ assert foo.value == ''
404
+ assert bar.value == nil
405
+ end
406
+ def test_0250
407
+ foo = nil
408
+ bar = nil
409
+ assert_nothing_raised{
410
+ main(%w[foo=40 bar=2]){
411
+ keyword('foo'){
412
+ cast :int
413
+ }
414
+ keyword('bar'){
415
+ cast :int
416
+ }
417
+ define_method('run'){
418
+ foo = param['foo']
419
+ bar = param['bar']
420
+ }
421
+ }
422
+ }
423
+ assert foo.value == 40
424
+ assert bar.value == 2
425
+ end
426
+ def test_0260
427
+ foo = nil
428
+ bar = nil
429
+ foobar = nil
430
+ assert_nothing_raised{
431
+ main(%w[foo=40 --bar=2 foobar foo=42]){
432
+ kw('foo'){ cast :int; arity 2 }
433
+ opt('bar='){ cast :int }
434
+ arg 'foobar'
435
+
436
+ define_method('run'){
437
+ foo = param['foo']
438
+ bar = param['bar']
439
+ foobar = param['foobar']
440
+ }
441
+ }
442
+ }
443
+ assert foo.value == 40
444
+ assert foo.values == [40, 42]
445
+ assert bar.value == 2
446
+ assert foobar.value == 'foobar'
447
+ end
448
+ def test_0270
449
+ foo = nil
450
+ assert_nothing_raised{
451
+ main([], 'foo' => '42'){
452
+ env('foo'){ cast :int }
453
+ define_method('run'){
454
+ foo = param['foo']
455
+ }
456
+ }
457
+ }
458
+ assert foo.value == 42
459
+ end
460
+ #
461
+ # usage
462
+ #
463
+ def test_0280
464
+ assert_nothing_raised{
465
+ u = Main::Usage.new
466
+ }
467
+ end
468
+ def test_0290
469
+ assert_nothing_raised{
470
+ u = Main::Usage.default main
471
+ }
472
+ end
473
+ def test_0300
474
+ assert_nothing_raised{
475
+ chunk = <<-txt
476
+ a
477
+ b
478
+ c
479
+ txt
480
+ assert Main::Util.unindent(chunk) == "a\nb\nc"
481
+ chunk = <<-txt
482
+ a
483
+ b
484
+ c
485
+ txt
486
+ assert Main::Util.unindent(chunk) == "a\n b\n c"
487
+ }
488
+ end
489
+ def test_0310
490
+ assert_nothing_raised{
491
+ u = Main::Usage.new
492
+ u[:name] = 'foobar'
493
+ assert u[:name] = 'foobar'
494
+ assert u['name'] = 'foobar'
495
+ }
496
+ end
497
+ def test_0320
498
+ assert_nothing_raised{
499
+ u = Main::Usage.new
500
+ u[:name] = 'foobar'
501
+ assert u[:name] == 'foobar'
502
+ assert u['name'] == 'foobar'
503
+ u[:name2] = 'barfoo'
504
+ assert u[:name] == 'foobar'
505
+ assert u['name'] == 'foobar'
506
+ assert u[:name2] == 'barfoo'
507
+ assert u['name2'] == 'barfoo'
508
+ u.delete_at :name
509
+ assert u[:name] == nil
510
+ assert u['name'] == nil
511
+ assert u[:name2] == 'barfoo'
512
+ assert u['name2'] == 'barfoo'
513
+ u.delete_at :name2
514
+ assert u[:name] == nil
515
+ assert u['name'] == nil
516
+ assert u[:name2] == nil
517
+ assert u['name2'] == nil
518
+ }
519
+ end
520
+
521
+ end
522
+
523
+