main 0.0.2 → 2.0.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.
@@ -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
@@ -0,0 +1,12 @@
1
+ module Main
2
+ module Softspoken
3
+ class << self
4
+ attribute 'softspoken' => true
5
+ def on!() softspoken(true) end
6
+ def off!() softspoken(false) end
7
+ def === other
8
+ softspoken ? super : false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -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("* #{ p.synopsis }", :indent => 2, :width => 78)
107
- ps << "\n"
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
@@ -0,0 +1,18 @@
1
+ require 'main'
2
+
3
+ Main {
4
+ argument 'global-argument'
5
+ option 'global-option'
6
+
7
+ def run() puts 'global-run' end
8
+
9
+ mode 'a' do
10
+ option 'a-option'
11
+ end
12
+
13
+ mode 'b' do
14
+ option 'b-option'
15
+
16
+ def run() puts 'b-run' end
17
+ end
18
+ }
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
- attr 'status'
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
- main = nil
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
- rescue Exception => e
34
- if SystemExit === e
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() raise end
111
+ def run() exit 42 end
96
112
  }
97
113
  }
98
- assert status == 1
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
- assert_nothing_raised{
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
- assert_nothing_raised{
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 main
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