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
data/README
CHANGED
@@ -2,18 +2,34 @@ NAME
|
|
2
2
|
main.rb
|
3
3
|
|
4
4
|
SYNOPSIS
|
5
|
-
a class factory and dsl for generating
|
5
|
+
a class factory and dsl for generating command line programs real quick
|
6
6
|
|
7
7
|
URI
|
8
8
|
http://rubyforge.org/projects/codeforpeople/
|
9
9
|
http://codeforpeople.com/lib/ruby/
|
10
10
|
|
11
11
|
INSTALL
|
12
|
-
|
12
|
+
gem install main
|
13
13
|
|
14
14
|
DESCRIPTION
|
15
|
-
main.rb
|
16
|
-
|
15
|
+
main.rb features the following:
|
16
|
+
|
17
|
+
- unification of option, argument, keyword, and environment parameter
|
18
|
+
parsing
|
19
|
+
- auto generation of usage and help messages
|
20
|
+
- support for mode/sub-commands
|
21
|
+
- io redirection support
|
22
|
+
- logging hooks using ruby's built-in logging mechanism
|
23
|
+
- intelligent error handling and exit codes
|
24
|
+
- use as dsl or library for building Main objects
|
25
|
+
- parsing user defined ARGV and ENV
|
26
|
+
- zero requirements for understanding the obtuse apis of *any* command
|
27
|
+
line option parsers
|
28
|
+
|
29
|
+
in short main.rb aims to drastically lower the barrier to writing uniform
|
30
|
+
command line applications.
|
31
|
+
|
32
|
+
for instance, this program
|
17
33
|
|
18
34
|
require 'main'
|
19
35
|
|
@@ -29,10 +45,34 @@ DESCRIPTION
|
|
29
45
|
}
|
30
46
|
|
31
47
|
sets up a program which requires one argument, 'bar', and which may accept one
|
32
|
-
command line switch, '--foo' in addition to the single option which is always
|
33
|
-
accepted and handled appropriately: '--help', '-h'.
|
48
|
+
command line switch, '--foo' in addition to the single option/mode which is always
|
49
|
+
accepted and handled appropriately: 'help', '--help', '-h'. for the most
|
50
|
+
part main.rb stays out of your command line namespace but insists that your
|
51
|
+
application has at least a help mode/option.
|
52
|
+
|
53
|
+
main.rb supports sub-commands in a very simple way
|
54
|
+
|
55
|
+
require 'main'
|
56
|
+
|
57
|
+
Main {
|
58
|
+
mode 'install' do
|
59
|
+
def run() puts 'installing...' end
|
60
|
+
end
|
61
|
+
|
62
|
+
mode 'uninstall' do
|
63
|
+
def run() puts 'uninstalling...' end
|
64
|
+
end
|
65
|
+
}
|
66
|
+
|
67
|
+
which allows you a program called 'a.rb' to be invoked as
|
34
68
|
|
35
|
-
|
69
|
+
ruby a.rb install
|
70
|
+
|
71
|
+
and
|
72
|
+
|
73
|
+
ruby a.rb uninstall
|
74
|
+
|
75
|
+
for simple programs main.rb is a real time saver but it's for more complex
|
36
76
|
applications where main.rb's unification of parameter parsing, class
|
37
77
|
configuration dsl, and auto-generation of usage messages can really streamline
|
38
78
|
command line application development. for example the following 'a.rb'
|
@@ -173,10 +213,9 @@ SAMPLES
|
|
173
213
|
a.rb foo [options]+
|
174
214
|
|
175
215
|
PARAMETERS
|
176
|
-
|
216
|
+
foo (1 -> int(foo))
|
177
217
|
the foo param
|
178
|
-
|
179
|
-
* --help, -h
|
218
|
+
--help, -h
|
180
219
|
|
181
220
|
|
182
221
|
|
@@ -216,10 +255,9 @@ SAMPLES
|
|
216
255
|
b.rb foo [options]+
|
217
256
|
|
218
257
|
PARAMETERS
|
219
|
-
|
258
|
+
foo (3 -> int(foo))
|
220
259
|
the foo param
|
221
|
-
|
222
|
-
* --help, -h
|
260
|
+
--help, -h
|
223
261
|
|
224
262
|
|
225
263
|
|
@@ -265,11 +303,9 @@ SAMPLES
|
|
265
303
|
c.rb foo=foo [bar=bar] [options]+
|
266
304
|
|
267
305
|
PARAMETERS
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
* --help, -h
|
306
|
+
foo=foo (2 -> float(foo))
|
307
|
+
bar=bar (1 ~> bool(bar))
|
308
|
+
--help, -h
|
273
309
|
|
274
310
|
|
275
311
|
|
@@ -320,22 +356,45 @@ SAMPLES
|
|
320
356
|
d.rb --foo=foo [options]+
|
321
357
|
|
322
358
|
PARAMETERS
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
* --help, -h
|
359
|
+
--foo=foo, -f (2 -> float(foo))
|
360
|
+
--bar=[bar], -b (1 ~> bool(bar=false))
|
361
|
+
--help, -h
|
328
362
|
|
329
363
|
|
330
364
|
|
331
365
|
DOCS
|
332
366
|
test/main.rb
|
333
367
|
|
334
|
-
|
368
|
+
vim -o lib/main.rb lib/main/*
|
335
369
|
|
336
370
|
API section below
|
337
371
|
|
338
372
|
HISTORY
|
373
|
+
2.0.0
|
374
|
+
- removed need for proxy.rb via Main::Base.wrap_run!
|
375
|
+
- added error handling hooks for parameter parsing
|
376
|
+
- bundled arrayfields, attributes, and pervasives although gems are tried
|
377
|
+
first
|
378
|
+
- softened error messages for parameter parsing errors: certain classes of
|
379
|
+
errors are now 'softspoken' and print only the message, not the entire
|
380
|
+
stacktrace, to stderr. much nicer for users. this is configurable.
|
381
|
+
- added subcommand/mode support
|
382
|
+
- added support for user defined exception handling on top level
|
383
|
+
exceptions/exits
|
384
|
+
- added support for negative arity. this users ruby's own arity
|
385
|
+
semantics, for example:
|
386
|
+
|
387
|
+
lambda{|*a|}.arity == -1
|
388
|
+
lambda{|a,*b|}.arity == -2
|
389
|
+
lambda{|a,b,*c|}.arity == -3
|
390
|
+
...
|
391
|
+
|
392
|
+
in otherwords parameters now support 'zero or more', 'one or more' ...
|
393
|
+
'n or more' argument semantics
|
394
|
+
|
395
|
+
1.0.0
|
396
|
+
- some improved usage messages from jeremy hinegardner
|
397
|
+
|
339
398
|
0.0.2
|
340
399
|
- removed dependancy on attributes/arrayfields. main now has zero gem
|
341
400
|
dependancies.
|
@@ -442,6 +501,57 @@ API
|
|
442
501
|
my own usage message
|
443
502
|
txt
|
444
503
|
|
504
|
+
###########################################################################
|
505
|
+
# MODE API #
|
506
|
+
###########################################################################
|
507
|
+
#
|
508
|
+
# modes are class factories that inherit from their parent class. they can
|
509
|
+
# be nested *arbitrarily* deep. usage messages are tailored for each mode.
|
510
|
+
# modes are, for the most part, independant classes but parameters are
|
511
|
+
# always a superset of the parent class - a mode accepts all of it's parents
|
512
|
+
# paramters *plus* and additional ones
|
513
|
+
#
|
514
|
+
option 'inherited-option'
|
515
|
+
argument 'inherited-argument'
|
516
|
+
|
517
|
+
mode 'install' do
|
518
|
+
option 'force' do
|
519
|
+
description 'clobber existing installation'
|
520
|
+
end
|
521
|
+
|
522
|
+
def run
|
523
|
+
inherited_method()
|
524
|
+
puts 'installing...'
|
525
|
+
end
|
526
|
+
|
527
|
+
mode 'docs' do
|
528
|
+
description 'installs the docs'
|
529
|
+
|
530
|
+
def run
|
531
|
+
puts 'installing docs...'
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
mode 'un-install' do
|
537
|
+
option 'force' do
|
538
|
+
description 'remove even if dependancies exist'
|
539
|
+
end
|
540
|
+
|
541
|
+
def run
|
542
|
+
inherited_method()
|
543
|
+
puts 'un-installing...'
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
def run
|
548
|
+
puts 'no mode yo?'
|
549
|
+
end
|
550
|
+
|
551
|
+
def inherited_method
|
552
|
+
puts 'superclass_method...'
|
553
|
+
end
|
554
|
+
|
445
555
|
|
446
556
|
###########################################################################
|
447
557
|
# PARAMETER API #
|
@@ -497,7 +607,8 @@ API
|
|
497
607
|
description 'a long description of foo'
|
498
608
|
#
|
499
609
|
# arity - indicates how many times the parameter should appear on the
|
500
|
-
# command line. the default is one.
|
610
|
+
# command line. the default is one. negative arities are supported and
|
611
|
+
# follow the same rules as ruby methods/procs.
|
501
612
|
#
|
502
613
|
arity 2
|
503
614
|
#
|
data/README.tmpl
CHANGED
@@ -2,18 +2,34 @@ NAME
|
|
2
2
|
main.rb
|
3
3
|
|
4
4
|
SYNOPSIS
|
5
|
-
a class factory and dsl for generating
|
5
|
+
a class factory and dsl for generating command line programs real quick
|
6
6
|
|
7
7
|
URI
|
8
8
|
http://rubyforge.org/projects/codeforpeople/
|
9
9
|
http://codeforpeople.com/lib/ruby/
|
10
10
|
|
11
11
|
INSTALL
|
12
|
-
|
12
|
+
gem install main
|
13
13
|
|
14
14
|
DESCRIPTION
|
15
|
-
main.rb
|
16
|
-
|
15
|
+
main.rb features the following:
|
16
|
+
|
17
|
+
- unification of option, argument, keyword, and environment parameter
|
18
|
+
parsing
|
19
|
+
- auto generation of usage and help messages
|
20
|
+
- support for mode/sub-commands
|
21
|
+
- io redirection support
|
22
|
+
- logging hooks using ruby's built-in logging mechanism
|
23
|
+
- intelligent error handling and exit codes
|
24
|
+
- use as dsl or library for building Main objects
|
25
|
+
- parsing user defined ARGV and ENV
|
26
|
+
- zero requirements for understanding the obtuse apis of *any* command
|
27
|
+
line option parsers
|
28
|
+
|
29
|
+
in short main.rb aims to drastically lower the barrier to writing uniform
|
30
|
+
command line applications.
|
31
|
+
|
32
|
+
for instance, this program
|
17
33
|
|
18
34
|
require 'main'
|
19
35
|
|
@@ -29,10 +45,34 @@ DESCRIPTION
|
|
29
45
|
}
|
30
46
|
|
31
47
|
sets up a program which requires one argument, 'bar', and which may accept one
|
32
|
-
command line switch, '--foo' in addition to the single option which is always
|
33
|
-
accepted and handled appropriately: '--help', '-h'.
|
48
|
+
command line switch, '--foo' in addition to the single option/mode which is always
|
49
|
+
accepted and handled appropriately: 'help', '--help', '-h'. for the most
|
50
|
+
part main.rb stays out of your command line namespace but insists that your
|
51
|
+
application has at least a help mode/option.
|
52
|
+
|
53
|
+
main.rb supports sub-commands in a very simple way
|
54
|
+
|
55
|
+
require 'main'
|
34
56
|
|
35
|
-
|
57
|
+
Main {
|
58
|
+
mode 'install' do
|
59
|
+
def run() puts 'installing...' end
|
60
|
+
end
|
61
|
+
|
62
|
+
mode 'uninstall' do
|
63
|
+
def run() puts 'uninstalling...' end
|
64
|
+
end
|
65
|
+
}
|
66
|
+
|
67
|
+
which allows you a program called 'a.rb' to be invoked as
|
68
|
+
|
69
|
+
ruby a.rb install
|
70
|
+
|
71
|
+
and
|
72
|
+
|
73
|
+
ruby a.rb uninstall
|
74
|
+
|
75
|
+
for simple programs main.rb is a real time saver but it's for more complex
|
36
76
|
applications where main.rb's unification of parameter parsing, class
|
37
77
|
configuration dsl, and auto-generation of usage messages can really streamline
|
38
78
|
command line application development. for example the following 'a.rb'
|
@@ -141,11 +181,36 @@ SAMPLES
|
|
141
181
|
DOCS
|
142
182
|
test/main.rb
|
143
183
|
|
144
|
-
|
184
|
+
vim -o lib/main.rb lib/main/*
|
145
185
|
|
146
186
|
API section below
|
147
187
|
|
148
188
|
HISTORY
|
189
|
+
2.0.0
|
190
|
+
- removed need for proxy.rb via Main::Base.wrap_run!
|
191
|
+
- added error handling hooks for parameter parsing
|
192
|
+
- bundled arrayfields, attributes, and pervasives although gems are tried
|
193
|
+
first
|
194
|
+
- softened error messages for parameter parsing errors: certain classes of
|
195
|
+
errors are now 'softspoken' and print only the message, not the entire
|
196
|
+
stacktrace, to stderr. much nicer for users. this is configurable.
|
197
|
+
- added subcommand/mode support
|
198
|
+
- added support for user defined exception handling on top level
|
199
|
+
exceptions/exits
|
200
|
+
- added support for negative arity. this users ruby's own arity
|
201
|
+
semantics, for example:
|
202
|
+
|
203
|
+
lambda{|*a|}.arity == -1
|
204
|
+
lambda{|a,*b|}.arity == -2
|
205
|
+
lambda{|a,b,*c|}.arity == -3
|
206
|
+
...
|
207
|
+
|
208
|
+
in otherwords parameters now support 'zero or more', 'one or more' ...
|
209
|
+
'n or more' argument semantics
|
210
|
+
|
211
|
+
1.0.0
|
212
|
+
- some improved usage messages from jeremy hinegardner
|
213
|
+
|
149
214
|
0.0.2
|
150
215
|
- removed dependancy on attributes/arrayfields. main now has zero gem
|
151
216
|
dependancies.
|
@@ -252,6 +317,57 @@ API
|
|
252
317
|
my own usage message
|
253
318
|
txt
|
254
319
|
|
320
|
+
###########################################################################
|
321
|
+
# MODE API #
|
322
|
+
###########################################################################
|
323
|
+
#
|
324
|
+
# modes are class factories that inherit from their parent class. they can
|
325
|
+
# be nested *arbitrarily* deep. usage messages are tailored for each mode.
|
326
|
+
# modes are, for the most part, independant classes but parameters are
|
327
|
+
# always a superset of the parent class - a mode accepts all of it's parents
|
328
|
+
# paramters *plus* and additional ones
|
329
|
+
#
|
330
|
+
option 'inherited-option'
|
331
|
+
argument 'inherited-argument'
|
332
|
+
|
333
|
+
mode 'install' do
|
334
|
+
option 'force' do
|
335
|
+
description 'clobber existing installation'
|
336
|
+
end
|
337
|
+
|
338
|
+
def run
|
339
|
+
inherited_method()
|
340
|
+
puts 'installing...'
|
341
|
+
end
|
342
|
+
|
343
|
+
mode 'docs' do
|
344
|
+
description 'installs the docs'
|
345
|
+
|
346
|
+
def run
|
347
|
+
puts 'installing docs...'
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
mode 'un-install' do
|
353
|
+
option 'force' do
|
354
|
+
description 'remove even if dependancies exist'
|
355
|
+
end
|
356
|
+
|
357
|
+
def run
|
358
|
+
inherited_method()
|
359
|
+
puts 'un-installing...'
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
def run
|
364
|
+
puts 'no mode yo?'
|
365
|
+
end
|
366
|
+
|
367
|
+
def inherited_method
|
368
|
+
puts 'superclass_method...'
|
369
|
+
end
|
370
|
+
|
255
371
|
|
256
372
|
###########################################################################
|
257
373
|
# PARAMETER API #
|
@@ -307,7 +423,8 @@ API
|
|
307
423
|
description 'a long description of foo'
|
308
424
|
#
|
309
425
|
# arity - indicates how many times the parameter should appear on the
|
310
|
-
# command line. the default is one.
|
426
|
+
# command line. the default is one. negative arities are supported and
|
427
|
+
# follow the same rules as ruby methods/procs.
|
311
428
|
#
|
312
429
|
arity 2
|
313
430
|
#
|
data/TODO
ADDED
data/a.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'main'
|
2
|
+
|
3
|
+
main(){
|
4
|
+
argument('foo'){
|
5
|
+
arity -1
|
6
|
+
}
|
7
|
+
|
8
|
+
mode 'a' do
|
9
|
+
argument('bar'){
|
10
|
+
arity -1
|
11
|
+
}
|
12
|
+
run {
|
13
|
+
foobar
|
14
|
+
puts 'a'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
run {
|
19
|
+
foobar
|
20
|
+
puts 'no mode'
|
21
|
+
}
|
22
|
+
|
23
|
+
def foobar
|
24
|
+
puts :foobar
|
25
|
+
end
|
26
|
+
}
|
data/gemspec.rb
CHANGED
@@ -22,6 +22,6 @@ Gem::Specification::new do |spec|
|
|
22
22
|
spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
|
23
23
|
|
24
24
|
spec.author = "Ara T. Howard"
|
25
|
-
spec.email = "ara.t.howard@
|
25
|
+
spec.email = "ara.t.howard@gmail.com"
|
26
26
|
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
27
27
|
end
|