main 2.5.0 → 2.6.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.
- data/README +126 -5
- data/TODO +10 -0
- data/a.rb +3 -20
- data/gemspec.rb +2 -1
- data/install.rb +2 -0
- data/lib/main.rb +4 -3
- data/lib/main/base.rb +88 -4
- data/lib/main/cast.rb +29 -3
- data/lib/main/logger.rb +51 -0
- data/lib/main/parameter.rb +133 -53
- data/lib/main/stdext.rb +29 -9
- data/lib/main/usage.rb +65 -23
- data/test/main.rb.bak +767 -0
- metadata +25 -5
data/lib/main/cast.rb
CHANGED
@@ -15,9 +15,9 @@ module Main
|
|
15
15
|
|
16
16
|
cast :boolean do |obj|
|
17
17
|
case obj.to_s
|
18
|
-
when
|
18
|
+
when %r/^(true|t|1)$/
|
19
19
|
true
|
20
|
-
when
|
20
|
+
when %r/^(false|f|0)$/
|
21
21
|
false
|
22
22
|
else
|
23
23
|
!!obj
|
@@ -40,17 +40,43 @@ module Main
|
|
40
40
|
String obj
|
41
41
|
end
|
42
42
|
|
43
|
+
cast :symbol do |obj|
|
44
|
+
String(obj).to_sym
|
45
|
+
end
|
46
|
+
|
43
47
|
cast :uri do |obj|
|
44
48
|
require 'uri'
|
45
49
|
::URI.parse obj.to_s
|
46
50
|
end
|
47
51
|
|
52
|
+
cast :time do |obj|
|
53
|
+
require 'time'
|
54
|
+
::Time.parse obj.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
cast :date do |obj|
|
58
|
+
require 'date'
|
59
|
+
::Date.parse obj.to_s
|
60
|
+
end
|
61
|
+
|
48
62
|
cast :list do |*objs|
|
49
63
|
[*objs].flatten.join(',').split(/,/)
|
50
64
|
end
|
51
65
|
|
66
|
+
# add list_of_xxx methods
|
67
|
+
List.dup.each do |type|
|
68
|
+
next if type.to_s =~ %r/list/
|
69
|
+
m = "list_of_#{ type }"
|
70
|
+
define_method m do |*objs|
|
71
|
+
list(*objs).map{|obj| send type, obj}
|
72
|
+
end
|
73
|
+
export m
|
74
|
+
List << m
|
75
|
+
end
|
76
|
+
|
77
|
+
# add list_of_xxx_from_file
|
52
78
|
List.dup.each do |type|
|
53
|
-
next if type.to_s
|
79
|
+
next if type.to_s =~ %r/list/
|
54
80
|
m = "list_of_#{ type }"
|
55
81
|
define_method m do |*objs|
|
56
82
|
list(*objs).map{|obj| send type, obj}
|
data/lib/main/logger.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Main
|
2
|
+
### because active_record fubars the hell out of Logger ;-(
|
3
|
+
class Logger < ::Logger
|
4
|
+
def self.new *a, &b
|
5
|
+
super(*a, &b).instance_eval{ @default_formatter = @formatter = Formatter.new; self }
|
6
|
+
end
|
7
|
+
def format_message(severity, datetime, progname, msg)
|
8
|
+
(@formatter || @default_formatter).call(severity, datetime, progname, msg)
|
9
|
+
end
|
10
|
+
|
11
|
+
def device
|
12
|
+
@logdev.instance_eval{ @dev }
|
13
|
+
end
|
14
|
+
|
15
|
+
def tty?
|
16
|
+
device.respond_to?('tty?') and device.tty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def turn which
|
20
|
+
@logdev.extend OnOff unless OnOff === @logdev
|
21
|
+
@logdev.turn which
|
22
|
+
end
|
23
|
+
|
24
|
+
def on
|
25
|
+
turn :on
|
26
|
+
end
|
27
|
+
alias_method "on!", "on"
|
28
|
+
def self.on *a, &b
|
29
|
+
new(*a, &b).instance_eval{ turn :on; self }
|
30
|
+
end
|
31
|
+
|
32
|
+
def off
|
33
|
+
turn :off
|
34
|
+
end
|
35
|
+
alias_method "off!", "off"
|
36
|
+
def self.off *a, &b
|
37
|
+
new(*a, &b).instance_eval{ turn :off; self }
|
38
|
+
end
|
39
|
+
|
40
|
+
module OnOff
|
41
|
+
def turn which
|
42
|
+
@turned = which.to_s =~ %r/on/i ? :on : :off
|
43
|
+
end
|
44
|
+
|
45
|
+
def write message
|
46
|
+
return message.to_s.size if @turned == :off
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/main/parameter.rb
CHANGED
@@ -65,6 +65,7 @@ module Main
|
|
65
65
|
attribute 'synopsis'
|
66
66
|
attribute('values'){ [] }
|
67
67
|
attribute('defaults'){ [] }
|
68
|
+
attribute('examples'){ [] }
|
68
69
|
|
69
70
|
attribute 'arity' => 1
|
70
71
|
attribute 'required' => false
|
@@ -94,6 +95,11 @@ module Main
|
|
94
95
|
end
|
95
96
|
|
96
97
|
DSL.evaluate(self, &block) if block
|
98
|
+
sanity_check!
|
99
|
+
end
|
100
|
+
|
101
|
+
def sanity_check!
|
102
|
+
raise Arity, "#{ name } with arity -1 (zero or more args) cannot be required" if(arity == -1 and required?)
|
97
103
|
end
|
98
104
|
|
99
105
|
def name
|
@@ -138,6 +144,7 @@ module Main
|
|
138
144
|
self.required !bool
|
139
145
|
end
|
140
146
|
|
147
|
+
=begin
|
141
148
|
def setup!
|
142
149
|
return false unless given?
|
143
150
|
adding_handlers do
|
@@ -147,9 +154,22 @@ module Main
|
|
147
154
|
end
|
148
155
|
true
|
149
156
|
end
|
157
|
+
=end
|
158
|
+
|
159
|
+
def setup!
|
160
|
+
adding_handlers do
|
161
|
+
check_arity
|
162
|
+
apply_casting
|
163
|
+
check_validation
|
164
|
+
end
|
165
|
+
end
|
150
166
|
|
151
167
|
def check_arity
|
152
|
-
|
168
|
+
return true if not given? and optional?
|
169
|
+
|
170
|
+
ex = values.size == 0 ? NotGiven : Arity
|
171
|
+
|
172
|
+
(raise ex, "#{ typename })" if values.size.zero? and argument_required?) unless arity == -1
|
153
173
|
|
154
174
|
if arity >= 0
|
155
175
|
min = arity
|
@@ -161,11 +181,19 @@ module Main
|
|
161
181
|
|
162
182
|
arity = min
|
163
183
|
|
184
|
+
=begin
|
185
|
+
puts
|
186
|
+
p :values => values
|
187
|
+
p :arity => arity
|
188
|
+
p :argument_required => argument_required?
|
189
|
+
p :argument_none => argument_none?
|
190
|
+
puts
|
191
|
+
=end
|
164
192
|
if values.size < arity
|
165
|
-
if
|
166
|
-
raise
|
167
|
-
elsif
|
168
|
-
raise
|
193
|
+
if argument_optional?
|
194
|
+
raise ex, "#{ typename }) #{ values.size }/#{ sign }#{ arity }" if(values.size < arity and values.size > 0)
|
195
|
+
elsif argument_required? or argument_none?
|
196
|
+
raise ex, "#{ typename }) #{ values.size }/#{ sign }#{ arity }" if(values.size < arity)
|
169
197
|
end
|
170
198
|
end
|
171
199
|
end
|
@@ -226,13 +254,14 @@ module Main
|
|
226
254
|
label = name
|
227
255
|
op = required ? "->" : "~>"
|
228
256
|
value = defaults.size > 0 ? "#{ name }=#{ defaults.join ',' }" : name
|
229
|
-
value = "#{ cast }(#{ value })" if cast
|
257
|
+
value = "#{ cast }(#{ value })" if(cast and not cast.respond_to?(:call))
|
230
258
|
"#{ label } (#{ arity } #{ op } #{ value })"
|
231
259
|
end
|
232
260
|
end
|
233
261
|
|
234
262
|
class Option < Parameter
|
235
263
|
attribute 'required' => false
|
264
|
+
attribute 'arity' => 0
|
236
265
|
|
237
266
|
attribute 'synopsis' do
|
238
267
|
long, *short = names
|
@@ -242,7 +271,7 @@ module Main
|
|
242
271
|
unless argument_none?
|
243
272
|
op = required ? "->" : "~>"
|
244
273
|
value = defaults.size > 0 ? "#{ name }=#{ defaults.join ',' }" : name
|
245
|
-
value = "#{ cast }(#{ value })" if cast
|
274
|
+
value = "#{ cast }(#{ value })" if(cast and not cast.respond_to?(:call))
|
246
275
|
"#{ label } (#{ arity } #{ op } #{ value })"
|
247
276
|
else
|
248
277
|
label
|
@@ -258,7 +287,7 @@ module Main
|
|
258
287
|
label = "#{ name }=#{ name }"
|
259
288
|
op = required ? "->" : "~>"
|
260
289
|
value = defaults.size > 0 ? "#{ name }=#{ defaults.join ',' }" : name
|
261
|
-
value = "#{ cast }(#{ value })" if cast
|
290
|
+
value = "#{ cast }(#{ value })" if(cast and not cast.respond_to?(:call))
|
262
291
|
"#{ label } (#{ arity } #{ op } #{ value })"
|
263
292
|
end
|
264
293
|
end
|
@@ -270,13 +299,18 @@ module Main
|
|
270
299
|
label = "env[#{ name }]=#{ name }"
|
271
300
|
op = required ? "->" : "~>"
|
272
301
|
value = defaults.size > 0 ? "#{ name }=#{ defaults.join ',' }" : name
|
273
|
-
value = "#{ cast }(#{ value })" if cast
|
302
|
+
value = "#{ cast }(#{ value })" if(cast and not cast.respond_to?(:call))
|
274
303
|
"#{ label } (#{ arity } #{ op } #{ value })"
|
275
304
|
end
|
276
305
|
end
|
277
306
|
|
278
307
|
class List < ::Array
|
279
308
|
def parse argv, env
|
309
|
+
ignore, stop = [], argv.index('--')
|
310
|
+
if stop
|
311
|
+
ignore = argv[stop .. -1]
|
312
|
+
(argv.size - stop).times{ argv.pop }
|
313
|
+
end
|
280
314
|
parse_options argv
|
281
315
|
return 'help' if detect{|p| p.name.to_s == 'help' and p.given?}
|
282
316
|
parse_keywords argv
|
@@ -284,6 +318,7 @@ module Main
|
|
284
318
|
parse_environment env
|
285
319
|
defaults!
|
286
320
|
validate!
|
321
|
+
argv.push *ignore[1 .. -1] unless ignore.empty?
|
287
322
|
self
|
288
323
|
end
|
289
324
|
|
@@ -330,9 +365,11 @@ module Main
|
|
330
365
|
raise ex
|
331
366
|
end
|
332
367
|
|
368
|
+
=begin
|
333
369
|
params.each do |p|
|
334
370
|
p.setup!
|
335
371
|
end
|
372
|
+
=end
|
336
373
|
end
|
337
374
|
|
338
375
|
def parse_arguments argv, params=nil
|
@@ -359,9 +396,11 @@ module Main
|
|
359
396
|
end
|
360
397
|
end
|
361
398
|
|
399
|
+
=begin
|
362
400
|
params.each do |p|
|
363
401
|
p.setup!
|
364
402
|
end
|
403
|
+
=end
|
365
404
|
end
|
366
405
|
|
367
406
|
def parse_keywords argv, params=nil
|
@@ -371,19 +410,27 @@ module Main
|
|
371
410
|
|
372
411
|
params.each do |p|
|
373
412
|
names = p.names
|
374
|
-
name = names.
|
413
|
+
name = names.sort_by{|n| [n.size,n]}.last
|
375
414
|
|
376
415
|
kre = %r/^\s*(#{ names.join '|' })\s*=/
|
377
416
|
opt = "--#{ name }"
|
378
|
-
i =
|
417
|
+
i = -1
|
379
418
|
|
380
419
|
argv.each_with_index do |a, idx|
|
420
|
+
i += 1
|
381
421
|
b = argv[idx + 1]
|
382
|
-
|
422
|
+
s = "#{ a }#{ b }"
|
423
|
+
m, key, *ignored = kre.match(s).to_a
|
383
424
|
if m
|
384
425
|
replacements[i] ||= a.gsub %r/^\s*#{ key }/, opt
|
426
|
+
next
|
385
427
|
end
|
386
|
-
|
428
|
+
=begin
|
429
|
+
abbrev = name.index(key) == 0
|
430
|
+
if abbrev
|
431
|
+
replacements[i] ||= a.gsub %r/^\s*#{ key }/, opt
|
432
|
+
end
|
433
|
+
=end
|
387
434
|
end
|
388
435
|
end
|
389
436
|
|
@@ -405,9 +452,11 @@ module Main
|
|
405
452
|
p.add_value value
|
406
453
|
end
|
407
454
|
|
455
|
+
=begin
|
408
456
|
params.each do |p|
|
409
457
|
p.setup!
|
410
458
|
end
|
459
|
+
=end
|
411
460
|
end
|
412
461
|
|
413
462
|
def defaults!
|
@@ -422,10 +471,11 @@ module Main
|
|
422
471
|
|
423
472
|
def validate!
|
424
473
|
each do |p|
|
425
|
-
p.adding_handlers do
|
426
|
-
next if p.arity == -1
|
427
|
-
raise NotGiven, "#{ p.typename } not given" if(p.required? and (not p.given?))
|
428
|
-
end
|
474
|
+
#p.adding_handlers do
|
475
|
+
#next if p.arity == -1
|
476
|
+
#raise NotGiven, "#{ p.typename } not given" if(p.required? and (not p.given?))
|
477
|
+
#end
|
478
|
+
p.setup!
|
429
479
|
end
|
430
480
|
end
|
431
481
|
|
@@ -465,115 +515,145 @@ module Main
|
|
465
515
|
def self.evaluate param, &block
|
466
516
|
new(param).evaluate(&block)
|
467
517
|
end
|
468
|
-
|
518
|
+
|
519
|
+
# attr 'p'
|
520
|
+
attr 'param'
|
469
521
|
alias_method 'evaluate', 'instance_eval'
|
470
522
|
def initialize param
|
471
|
-
@
|
523
|
+
@param = param
|
524
|
+
end
|
525
|
+
|
526
|
+
def attribute a = nil, &block
|
527
|
+
name = param.name
|
528
|
+
a ||= name
|
529
|
+
b = attribute_block_for name, &block
|
530
|
+
Main.current.module_eval{ attribute *a, &b }
|
531
|
+
end
|
532
|
+
|
533
|
+
def attribute_block_for name, &block
|
534
|
+
#block ||= lambda{|param| param.arity == 1 ? param.value : param.values}
|
535
|
+
block ||= lambda{|param| param.arity.abs <= 1 ? param.value : param.values }
|
536
|
+
lambda{ block.call self.param[name] }
|
537
|
+
end
|
538
|
+
|
539
|
+
def attr *a, &b
|
540
|
+
attribute *a, &b
|
541
|
+
end
|
542
|
+
|
543
|
+
def example *list
|
544
|
+
list.flatten.compact.each do |elem|
|
545
|
+
param.examples << elem.to_s
|
546
|
+
end
|
472
547
|
end
|
548
|
+
alias_method "examples", "example"
|
473
549
|
|
474
|
-
|
475
|
-
|
550
|
+
|
551
|
+
def type *sym
|
552
|
+
sym.size == 0 ? param.type : (param.type = sym.first)
|
476
553
|
end
|
477
554
|
def type?
|
478
|
-
|
555
|
+
param.type?
|
479
556
|
end
|
480
557
|
|
481
|
-
def synopsis arg
|
482
|
-
|
558
|
+
def synopsis *arg
|
559
|
+
arg.size == 0 ? param.synopsis : (param.synopsis arg.first)
|
483
560
|
end
|
484
561
|
|
485
562
|
def argument arg
|
486
|
-
|
563
|
+
param.argument arg
|
487
564
|
end
|
488
565
|
def argument_required bool = true
|
489
566
|
if bool
|
490
|
-
|
567
|
+
param.argument :required
|
491
568
|
else
|
492
|
-
|
569
|
+
param.argument false
|
493
570
|
end
|
494
571
|
end
|
495
572
|
def argument_required?
|
496
|
-
|
573
|
+
param.argument_required?
|
497
574
|
end
|
498
575
|
|
499
576
|
def argument_optional bool = true
|
500
577
|
if bool
|
501
|
-
|
578
|
+
param.argument :optional
|
502
579
|
else
|
503
|
-
|
580
|
+
param.argument false
|
504
581
|
end
|
505
582
|
end
|
506
583
|
def argument_optional?
|
507
|
-
|
584
|
+
param.argument_optional?
|
508
585
|
end
|
509
586
|
|
510
587
|
def required bool = true
|
511
|
-
|
588
|
+
param.required = bool
|
512
589
|
end
|
513
590
|
def required?
|
514
|
-
|
591
|
+
param.required?
|
515
592
|
end
|
516
593
|
|
517
594
|
def optional bool = true
|
518
595
|
if bool
|
519
|
-
|
596
|
+
param.required !bool
|
520
597
|
else
|
521
|
-
|
598
|
+
param.required bool
|
522
599
|
end
|
523
600
|
end
|
524
601
|
def optional?
|
525
|
-
|
602
|
+
param.optional?
|
526
603
|
end
|
527
604
|
|
528
605
|
def cast sym=nil, &b
|
529
|
-
|
606
|
+
param.cast = sym || b
|
530
607
|
end
|
531
608
|
def cast?
|
532
|
-
|
609
|
+
param.cast?
|
533
610
|
end
|
534
611
|
|
535
612
|
def validate sym=nil, &b
|
536
|
-
|
613
|
+
param.validate = sym || b
|
537
614
|
end
|
538
615
|
def validate?
|
539
|
-
|
616
|
+
param.validate?
|
540
617
|
end
|
541
618
|
|
542
619
|
def description s
|
543
|
-
|
620
|
+
param.description = s.to_s
|
544
621
|
end
|
545
622
|
def description?
|
546
|
-
|
623
|
+
param.description?
|
547
624
|
end
|
548
625
|
alias_method 'desc', 'description'
|
549
626
|
|
550
627
|
def default value, *values
|
551
|
-
|
552
|
-
|
553
|
-
|
628
|
+
param.defaults.push value
|
629
|
+
param.defaults.push *values
|
630
|
+
param.defaults
|
554
631
|
end
|
555
632
|
def defaults?
|
556
|
-
|
633
|
+
param.defaults?
|
557
634
|
end
|
558
635
|
def defaults value, *values
|
559
|
-
|
560
|
-
|
561
|
-
|
636
|
+
param.defaults.push value
|
637
|
+
param.defaults.push *values
|
638
|
+
param.defaults
|
562
639
|
end
|
563
640
|
def defaults?
|
564
|
-
|
641
|
+
param.defaults?
|
565
642
|
end
|
566
643
|
|
567
644
|
def arity value
|
568
645
|
value = -1 if value.to_s == '*'
|
569
|
-
|
646
|
+
param.arity = Integer value
|
647
|
+
if param.arity == -1
|
648
|
+
optional true
|
649
|
+
end
|
570
650
|
end
|
571
651
|
def arity?
|
572
|
-
|
652
|
+
param.arity?
|
573
653
|
end
|
574
654
|
|
575
655
|
def error which = :instead, &block
|
576
|
-
|
656
|
+
param.send "error_handler_#{ which }=", block
|
577
657
|
end
|
578
658
|
end
|
579
659
|
|