main 0.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +136 -25
- data/README.tmpl +126 -9
- data/TODO +2 -0
- data/a.rb +26 -0
- data/gemspec.rb +1 -1
- data/gen_readme.rb +4 -0
- data/lib/arrayfields.rb +434 -0
- data/lib/main.rb +46 -17
- data/lib/main/arrayfields.rb +190 -103
- data/lib/main/attributes.rb +84 -25
- data/lib/main/base.rb +146 -23
- data/lib/main/factories.rb +12 -8
- data/lib/main/mode.rb +42 -0
- data/lib/main/parameter.rb +77 -38
- data/lib/main/pervasives.rb +52 -0
- data/lib/main/softspoken.rb +12 -0
- data/lib/main/stdext.rb +18 -0
- data/lib/main/usage.rb +21 -3
- data/samples/e.rb +18 -0
- data/samples/f.rb +27 -0
- data/test/main.rb +156 -30
- metadata +25 -17
- data/lib/main/proxy.rb +0 -54
@@ -0,0 +1,52 @@
|
|
1
|
+
module Pervasives
|
2
|
+
VERSION = "1.1.0"
|
3
|
+
def self.version() VERSION end
|
4
|
+
|
5
|
+
Methods = Hash.new{|h,k| h[k] = {}}
|
6
|
+
|
7
|
+
[Class, Module, Object].each do |type|
|
8
|
+
type.instance_methods.each do |m|
|
9
|
+
Methods[type]["#{ m }"] = type.instance_method m
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.call o, m, *a, &b
|
14
|
+
list =
|
15
|
+
case o
|
16
|
+
when Class then [Class, Module, Object]
|
17
|
+
when Module then [Module, Object]
|
18
|
+
when Object then [Object]
|
19
|
+
end
|
20
|
+
type = list.detect{|type| Methods[type]["#{ m }"]}
|
21
|
+
m = Methods[type]["#{ m }"]
|
22
|
+
( m ).bind( o ).call( *a, &b )
|
23
|
+
end
|
24
|
+
|
25
|
+
class ::Object
|
26
|
+
def __pervasive__ m, *a, &b
|
27
|
+
Pervasives.call self, m, *a, &b
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Proxy
|
32
|
+
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
33
|
+
|
34
|
+
def initialize obj
|
35
|
+
@obj = obj
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing m, *a, &b
|
39
|
+
Pervasives.call @obj, m, *a, &b
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.new *a, &b
|
44
|
+
Proxy.new *a, &b
|
45
|
+
end
|
46
|
+
|
47
|
+
class ::Object
|
48
|
+
def Pervasives *a, &b
|
49
|
+
Proxy.new *a, &b
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/main/stdext.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class ::Logger
|
2
|
+
def device
|
3
|
+
@logdev.instance_eval{ @dev }
|
4
|
+
end
|
5
|
+
def tty?
|
6
|
+
device.respond_to?('tty?') and device.tty?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Object
|
11
|
+
def singleton_class object = self, &block
|
12
|
+
sc =
|
13
|
+
class << object
|
14
|
+
self
|
15
|
+
end
|
16
|
+
block ? sc.module_eval(&block) : sc
|
17
|
+
end
|
18
|
+
end
|
data/lib/main/usage.rb
CHANGED
@@ -26,8 +26,20 @@ module Main
|
|
26
26
|
alias_method 'delete', 'delete_at'
|
27
27
|
|
28
28
|
def self.default_synopsis main
|
29
|
+
# build up synopsis
|
29
30
|
s = "#{ main.name }"
|
30
31
|
|
32
|
+
# mode info
|
33
|
+
if main.mode_name != 'main'
|
34
|
+
s << " #{ main.fully_qualified_mode.join ' ' }"
|
35
|
+
end
|
36
|
+
|
37
|
+
unless main.modes.empty?
|
38
|
+
modes = main.modes.keys.join('|')
|
39
|
+
s << " (#{ modes })"
|
40
|
+
end
|
41
|
+
|
42
|
+
# argument info
|
31
43
|
main.parameters.each do |p|
|
32
44
|
if p.type == :argument
|
33
45
|
if p.required?
|
@@ -38,6 +50,7 @@ module Main
|
|
38
50
|
end
|
39
51
|
end
|
40
52
|
|
53
|
+
# keyword info
|
41
54
|
main.parameters.each do |p|
|
42
55
|
if p.type == :keyword
|
43
56
|
if p.required?
|
@@ -48,6 +61,7 @@ module Main
|
|
48
61
|
end
|
49
62
|
end
|
50
63
|
|
64
|
+
# option info
|
51
65
|
n = 0
|
52
66
|
main.parameters.each do |p|
|
53
67
|
if p.type == :option
|
@@ -103,12 +117,16 @@ module Main
|
|
103
117
|
s =
|
104
118
|
parameters.map do |p|
|
105
119
|
ps = ''
|
106
|
-
ps << Util.columnize("
|
107
|
-
ps << "
|
120
|
+
ps << Util.columnize("#{ p.synopsis }", :indent => 2, :width => 78)
|
121
|
+
#ps << Util.columnize("* #{ p.synopsis }", :indent => 2, :width => 78)
|
122
|
+
#ps << "\n"
|
108
123
|
if p.description?
|
109
|
-
ps << Util.columnize(p.description, :indent => 6, :width => 78)
|
110
124
|
ps << "\n"
|
125
|
+
ps << Util.columnize("#{ p.description }", :indent => 6, :width => 78)
|
126
|
+
#ps << Util.columnize(p.description, :indent => 6, :width => 78)
|
127
|
+
#ps << "\n"
|
111
128
|
end
|
129
|
+
#ps << "\n"
|
112
130
|
ps
|
113
131
|
end.join("\n")
|
114
132
|
usage['parameters'] = s
|
data/samples/e.rb
ADDED
data/samples/f.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'main'
|
2
|
+
|
3
|
+
Main {
|
4
|
+
argument('directory'){ description 'the directory to operate on' }
|
5
|
+
|
6
|
+
option('force'){ description 'use a bigger hammer' }
|
7
|
+
|
8
|
+
def run
|
9
|
+
puts 'this is how we run when no mode is specified'
|
10
|
+
end
|
11
|
+
|
12
|
+
mode 'compress' do
|
13
|
+
option('bzip'){ description 'use bzip compression' }
|
14
|
+
|
15
|
+
def run
|
16
|
+
puts 'this is how we run in compress mode'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
mode 'uncompress' do
|
21
|
+
option('delete-after'){ description 'delete orginal file after uncompressing' }
|
22
|
+
|
23
|
+
def run
|
24
|
+
puts 'this is how we run in un-compress mode'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
}
|
data/test/main.rb
CHANGED
@@ -8,10 +8,12 @@ require 'test/unit'
|
|
8
8
|
require 'main'
|
9
9
|
|
10
10
|
class T < Test::Unit::TestCase
|
11
|
-
|
11
|
+
attribute 'status'
|
12
|
+
attribute 'logger'
|
13
|
+
attribute 'error'
|
12
14
|
|
13
15
|
def setup
|
14
|
-
@status = nil
|
16
|
+
@status = nil
|
15
17
|
@logger = Logger.new StringIO.new
|
16
18
|
@error = nil
|
17
19
|
end
|
@@ -21,22 +23,36 @@ class T < Test::Unit::TestCase
|
|
21
23
|
|
22
24
|
def main argv=[], env={}, &b
|
23
25
|
at_exit{ exit! }
|
26
|
+
|
24
27
|
$VERBOSE=nil
|
25
28
|
ARGV.replace argv
|
26
29
|
ENV.clear
|
27
30
|
env.each{|k,v| ENV[k.to_s]=v.to_s}
|
28
|
-
|
31
|
+
|
32
|
+
this = self
|
33
|
+
|
34
|
+
klass = ::Main.create do
|
35
|
+
module_eval &b if b
|
36
|
+
|
37
|
+
define_method :handle_exception do |e|
|
38
|
+
if e.respond_to? :status
|
39
|
+
this.status = e.status
|
40
|
+
else
|
41
|
+
raise
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
main = klass.new argv, env
|
47
|
+
|
48
|
+
main.logger = @logger
|
49
|
+
|
29
50
|
begin
|
30
|
-
main = Object::Main.new(&b)
|
31
|
-
main.logger = @logger
|
32
51
|
main.run
|
33
|
-
|
34
|
-
|
35
|
-
@status = e.status
|
36
|
-
else
|
37
|
-
raise
|
38
|
-
end
|
52
|
+
ensure
|
53
|
+
this.status ||= main.exit_status
|
39
54
|
end
|
55
|
+
|
40
56
|
main
|
41
57
|
end
|
42
58
|
|
@@ -92,10 +108,10 @@ class T < Test::Unit::TestCase
|
|
92
108
|
def test_0050
|
93
109
|
assert_nothing_raised{
|
94
110
|
main{
|
95
|
-
def run()
|
111
|
+
def run() exit 42 end
|
96
112
|
}
|
97
113
|
}
|
98
|
-
assert status ==
|
114
|
+
assert status == 42
|
99
115
|
end
|
100
116
|
def test_0060
|
101
117
|
assert_nothing_raised{
|
@@ -106,7 +122,7 @@ class T < Test::Unit::TestCase
|
|
106
122
|
assert status == 1
|
107
123
|
end
|
108
124
|
def test_0060
|
109
|
-
|
125
|
+
assert_raises(RuntimeError){
|
110
126
|
main{
|
111
127
|
def run() exit_status 42; raise end
|
112
128
|
}
|
@@ -114,7 +130,7 @@ class T < Test::Unit::TestCase
|
|
114
130
|
assert status == 42
|
115
131
|
end
|
116
132
|
def test_0070
|
117
|
-
|
133
|
+
assert_raises(ArgumentError){
|
118
134
|
main{
|
119
135
|
def run() exit_status 42; raise ArgumentError end
|
120
136
|
}
|
@@ -124,18 +140,6 @@ class T < Test::Unit::TestCase
|
|
124
140
|
#
|
125
141
|
# parameter parsing
|
126
142
|
#
|
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
143
|
def test_0080
|
140
144
|
p = nil
|
141
145
|
assert_raises(Main::Parameter::NotGiven){
|
@@ -147,17 +151,19 @@ class T < Test::Unit::TestCase
|
|
147
151
|
end
|
148
152
|
def test_0090
|
149
153
|
p = nil
|
154
|
+
m = nil
|
150
155
|
argv = %w[ 42 ]
|
151
156
|
given = nil
|
152
157
|
assert_nothing_raised{
|
153
|
-
main(argv){
|
158
|
+
main(argv.dup){
|
154
159
|
argument 'foo'
|
155
|
-
define_method('run'){ p = param['foo'] }
|
160
|
+
define_method('run'){ m = self; p = param['foo'] }
|
156
161
|
}
|
157
162
|
}
|
158
163
|
assert p.value == argv.first
|
159
164
|
assert p.values == argv
|
160
165
|
assert p.given?
|
166
|
+
assert m.argv.empty?
|
161
167
|
end
|
162
168
|
def test_0100
|
163
169
|
p = nil
|
@@ -467,7 +473,7 @@ class T < Test::Unit::TestCase
|
|
467
473
|
end
|
468
474
|
def test_0290
|
469
475
|
assert_nothing_raised{
|
470
|
-
u = Main::Usage.default
|
476
|
+
u = Main::Usage.default Main.create
|
471
477
|
}
|
472
478
|
end
|
473
479
|
def test_0300
|
@@ -633,6 +639,126 @@ class T < Test::Unit::TestCase
|
|
633
639
|
assert argv == $argv
|
634
640
|
end
|
635
641
|
|
642
|
+
#
|
643
|
+
# negative/globbing arity
|
644
|
+
#
|
645
|
+
def test_4000
|
646
|
+
m = nil
|
647
|
+
argv = %w( a b c )
|
648
|
+
assert_nothing_raised{
|
649
|
+
main(argv.dup) {
|
650
|
+
argument('zero_or_more'){ arity -1 }
|
651
|
+
run{ m = self }
|
652
|
+
}
|
653
|
+
}
|
654
|
+
assert m.param['zero_or_more'].values == argv
|
655
|
+
end
|
656
|
+
def test_4010
|
657
|
+
m = nil
|
658
|
+
argv = %w( a b c )
|
659
|
+
assert_nothing_raised{
|
660
|
+
main(argv.dup) {
|
661
|
+
argument('zero_or_more'){ arity '*' }
|
662
|
+
run{ m = self }
|
663
|
+
}
|
664
|
+
}
|
665
|
+
assert m.param['zero_or_more'].values == argv
|
666
|
+
end
|
667
|
+
def test_4020
|
668
|
+
m = nil
|
669
|
+
argv = %w( a b c )
|
670
|
+
assert_nothing_raised{
|
671
|
+
main(argv.dup) {
|
672
|
+
argument('one_or_more'){ arity -2 }
|
673
|
+
run{ m = self }
|
674
|
+
}
|
675
|
+
}
|
676
|
+
assert m.param['one_or_more'].values == argv
|
677
|
+
end
|
678
|
+
def test_4030
|
679
|
+
m = nil
|
680
|
+
argv = %w( a b c )
|
681
|
+
assert_nothing_raised{
|
682
|
+
main(argv.dup) {
|
683
|
+
argument('two_or_more'){ arity -3 }
|
684
|
+
run{ m = self }
|
685
|
+
}
|
686
|
+
}
|
687
|
+
assert m.param['two_or_more'].values == argv
|
688
|
+
end
|
689
|
+
def test_4040
|
690
|
+
m = nil
|
691
|
+
argv = %w()
|
692
|
+
assert_nothing_raised{
|
693
|
+
main(argv.dup) {
|
694
|
+
argument('zero_or_more'){ arity -1 }
|
695
|
+
run{ m = self }
|
696
|
+
}
|
697
|
+
}
|
698
|
+
assert m.param['zero_or_more'].values == argv
|
699
|
+
end
|
700
|
+
def test_4050
|
701
|
+
m = nil
|
702
|
+
argv = %w()
|
703
|
+
assert_raises(Main::Parameter::NotGiven){
|
704
|
+
main(argv.dup) {
|
705
|
+
argument('one_or_more'){ arity -2 }
|
706
|
+
run{ m = self }
|
707
|
+
}
|
708
|
+
}
|
709
|
+
end
|
710
|
+
def test_4060
|
711
|
+
m = nil
|
712
|
+
argv = %w( a )
|
713
|
+
assert_raises(Main::Parameter::Arity){
|
714
|
+
main(argv.dup) {
|
715
|
+
argument('two_or_more'){ arity -3 }
|
716
|
+
run{ m = self }
|
717
|
+
}
|
718
|
+
}
|
719
|
+
end
|
720
|
+
def test_4070
|
721
|
+
m = nil
|
722
|
+
argv = %w( a )
|
723
|
+
assert_raises(Main::Parameter::Arity){
|
724
|
+
main(argv.dup) {
|
725
|
+
argument('two_or_more'){ arity -4 }
|
726
|
+
run{ m = self }
|
727
|
+
}
|
728
|
+
}
|
729
|
+
end
|
730
|
+
#
|
731
|
+
# sub-command/mode functionality
|
732
|
+
#
|
733
|
+
def test_4080
|
734
|
+
m = nil
|
735
|
+
argv = %w( a b )
|
736
|
+
assert_nothing_raised{
|
737
|
+
main(argv.dup) {
|
738
|
+
mode 'a' do
|
739
|
+
argument 'b'
|
740
|
+
run{ m = self }
|
741
|
+
end
|
742
|
+
}
|
743
|
+
}
|
744
|
+
assert m.param['b'].value == 'b'
|
745
|
+
end
|
746
|
+
def test_4090
|
747
|
+
m = nil
|
748
|
+
argv = %w( a b c )
|
749
|
+
assert_nothing_raised{
|
750
|
+
main(argv.dup) {
|
751
|
+
mode 'a' do
|
752
|
+
mode 'b' do
|
753
|
+
argument 'c'
|
754
|
+
run{ m = self }
|
755
|
+
end
|
756
|
+
end
|
757
|
+
}
|
758
|
+
}
|
759
|
+
assert m.param['c'].value == 'c'
|
760
|
+
end
|
761
|
+
|
636
762
|
end
|
637
763
|
|
638
764
|
|