trollop 1.9 → 1.10
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/FAQ.txt +0 -9
- data/History.txt +5 -0
- data/README.txt +1 -59
- data/lib/trollop.rb +96 -82
- data/test/test_trollop.rb +22 -0
- metadata +4 -4
data/FAQ.txt
CHANGED
@@ -33,12 +33,3 @@ A: Because it's ambiguous whether these are arguments or negative
|
|
33
33
|
that require floating-point parameters, and allow such short option
|
34
34
|
names in those cases, but opted for simplicity and consistency.
|
35
35
|
|
36
|
-
Q: Why does Trollop disallow options appearing multiple times, despite
|
37
|
-
the POSIX standard allowing it?
|
38
|
-
A: Because basically I think it's confusing, and more often than
|
39
|
-
not, a symptom of you making a mistake (e.g. getting lost in a long
|
40
|
-
command line and accidentally setting the same thing twice.)
|
41
|
-
I also don't see that much advantage to "-vvvvv" over "-v 5", so
|
42
|
-
Trollop will produce an error if you try to use the same argument
|
43
|
-
multiple times.
|
44
|
-
|
data/History.txt
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
== 1.10 / 2008-10-21
|
2
|
+
* Added :io type for parameters that point to IO streams (filenames, URIs, etc).
|
3
|
+
* For screen size detection, first try `stty size` before loading Curses.
|
4
|
+
* Improved documentation.
|
5
|
+
|
1
6
|
== 1.9 / 2008-08-20
|
2
7
|
* Added 'stop_on_unknown' command to stop parsing on any unknown argument.
|
3
8
|
This is useful for handling sub-commands when you don't know the entire
|
data/README.txt
CHANGED
@@ -23,62 +23,6 @@ subcompletion, and sensible defaults for everything you don't specify.
|
|
23
23
|
- Automatic help message generation, wrapped to current screen width.
|
24
24
|
- Lots of unit tests.
|
25
25
|
|
26
|
-
== SYNOPSIS
|
27
|
-
|
28
|
-
####################
|
29
|
-
###### simple ######
|
30
|
-
####################
|
31
|
-
|
32
|
-
require 'trollop'
|
33
|
-
opts = Trollop::options do
|
34
|
-
opt :monkey, "Use monkey mode"
|
35
|
-
opt :goat, "Use goat mode", :default => true
|
36
|
-
opt :num_limbs, "Set number of limbs", :default => 4
|
37
|
-
end
|
38
|
-
|
39
|
-
p opts # { :monkey => false, :goat => true, :num_limbs => 4 }
|
40
|
-
|
41
|
-
####################
|
42
|
-
###### medium ######
|
43
|
-
####################
|
44
|
-
|
45
|
-
require 'trollop'
|
46
|
-
opts = Trollop::options do
|
47
|
-
version "test 1.2.3 (c) 2007 William Morgan"
|
48
|
-
banner <<-EOS
|
49
|
-
Test is an awesome program that does something very, very important.
|
50
|
-
|
51
|
-
Usage:
|
52
|
-
test [options] <filenames>+
|
53
|
-
where [options] are:
|
54
|
-
EOS
|
55
|
-
|
56
|
-
opt :ignore, "Ignore incorrect values"
|
57
|
-
opt :file, "Extra data filename to read in, with a very long option description like this one", :type => String
|
58
|
-
opt :volume, "Volume level", :default => 3.0
|
59
|
-
opt :iters, "Number of iterations", :default => 5
|
60
|
-
end
|
61
|
-
Trollop::die :volume, "must be non-negative" if opts[:volume] < 0
|
62
|
-
Trollop::die :file, "must exist" unless File.exist?(opts[:file]) if opts[:file]
|
63
|
-
################################
|
64
|
-
##### sub-command support ######
|
65
|
-
################################
|
66
|
-
|
67
|
-
require 'trollop'
|
68
|
-
global_opts = Trollop::options do
|
69
|
-
opt :global_option, "This is a global option"
|
70
|
-
stop_on %w(sub-command-1 sub-command-2)
|
71
|
-
end
|
72
|
-
|
73
|
-
cmd = ARGV.shift
|
74
|
-
cmd_opts = Trollop::options do
|
75
|
-
opt :cmd_option, "This is an option only for the subcommand"
|
76
|
-
end
|
77
|
-
|
78
|
-
p global_opts
|
79
|
-
p cmd
|
80
|
-
p cmd_opts
|
81
|
-
|
82
26
|
== REQUIREMENTS
|
83
27
|
|
84
28
|
* A burning desire to write less code.
|
@@ -89,6 +33,4 @@ subcompletion, and sensible defaults for everything you don't specify.
|
|
89
33
|
|
90
34
|
== LICENSE
|
91
35
|
|
92
|
-
Copyright (c) 2008 William Morgan.
|
93
|
-
|
94
|
-
Trollop is distributed under the same terms as Ruby.
|
36
|
+
Copyright (c) 2008 William Morgan. Trollop is distributed under the same terms as Ruby.
|
data/lib/trollop.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
module Trollop
|
7
7
|
|
8
|
-
VERSION = "1.
|
8
|
+
VERSION = "1.10"
|
9
9
|
|
10
10
|
## Thrown by Parser in the event of a commandline error. Not needed if
|
11
11
|
## you're using the Trollop::options entry.
|
@@ -26,26 +26,31 @@ FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))$/
|
|
26
26
|
PARAM_RE = /^-(-|\.$|[^\d\.])/
|
27
27
|
|
28
28
|
## The commandline parser. In typical usage, the methods in this class
|
29
|
-
## will be handled internally by Trollop#options
|
30
|
-
##
|
29
|
+
## will be handled internally by Trollop#options. In this case, only the
|
30
|
+
## #opt, #banner and #version, #depends, and #conflicts methods will
|
31
31
|
## typically be called.
|
32
|
+
##
|
33
|
+
## If it's necessary to instantiate this class (for more complicated
|
34
|
+
## argument-parsing situations), be sure to call #parse to actually
|
35
|
+
## produce the output hash.
|
32
36
|
class Parser
|
33
37
|
|
34
|
-
## The set of values that indicate a flag
|
35
|
-
##
|
38
|
+
## The set of values that indicate a flag option when passed as the
|
39
|
+
## +:type+ parameter of #opt.
|
36
40
|
FLAG_TYPES = [:flag, :bool, :boolean]
|
37
41
|
|
38
|
-
## The set of values that indicate
|
39
|
-
##
|
40
|
-
##
|
41
|
-
|
42
|
+
## The set of values that indicate a single-parameter option when
|
43
|
+
## passed as the +:type+ parameter of #opt.
|
44
|
+
##
|
45
|
+
## A value of +io+ corresponds to a readable IO resource, including
|
46
|
+
## a filename, URI, or the strings 'stdin' or '-'.
|
47
|
+
SINGLE_ARG_TYPES = [:int, :integer, :string, :double, :float, :io]
|
42
48
|
|
43
|
-
## The set of values that indicate
|
44
|
-
##
|
45
|
-
|
46
|
-
MULTI_ARG_TYPES = [:ints, :integers, :strings, :doubles, :floats]
|
49
|
+
## The set of values that indicate a multiple-parameter option when
|
50
|
+
## passed as the +:type+ parameter of #opt.
|
51
|
+
MULTI_ARG_TYPES = [:ints, :integers, :strings, :doubles, :floats, :ios]
|
47
52
|
|
48
|
-
## The set of values
|
53
|
+
## The complete set of legal values for the +:type+ parameter of #opt.
|
49
54
|
TYPES = FLAG_TYPES + SINGLE_ARG_TYPES + MULTI_ARG_TYPES
|
50
55
|
|
51
56
|
INVALID_SHORT_ARG_REGEX = /[\d-]/ #:nodoc:
|
@@ -73,62 +78,44 @@ class Parser
|
|
73
78
|
cloaker(&b).bind(self).call(*a) if b
|
74
79
|
end
|
75
80
|
|
76
|
-
##
|
77
|
-
## for the option that you will use internally.
|
78
|
-
## description which will be displayed
|
79
|
-
##
|
81
|
+
## Define an option. +name+ is the option name, a unique identifier
|
82
|
+
## for the option that you will use internally. This should probably
|
83
|
+
## be a symbol. +desc+ is a string description which will be displayed
|
84
|
+
## in help messages.
|
80
85
|
##
|
81
|
-
##
|
82
|
-
##
|
83
|
-
##
|
84
|
-
##
|
85
|
-
##
|
86
|
-
##
|
87
|
-
##
|
88
|
-
##
|
89
|
-
## member of the SINGLE_ARG_TYPES constant or a corresponding class
|
90
|
-
## (e.g. Integer for :int). For multiple parameters, the value can
|
91
|
-
## be a member of the MULTI_ARG_TYPES constant. If unset, the
|
92
|
-
## default argument type is :flag, meaning that the argument does
|
93
|
-
## not take a parameter. The specification of :type is not
|
94
|
-
## necessary if :default is given.
|
95
|
-
## * :default: Set the default value for an argument. Without a
|
96
|
-
## default value, the hash returned by #parse (and thus
|
97
|
-
## Trollop#options) will not contain the argument unless it is
|
98
|
-
## given on the commandline. The argument type is derived
|
99
|
-
## automatically from the class of the default value given, if
|
100
|
-
## any. Specifying a :flag argument on the commandline whose
|
101
|
-
## default value is true will change its value to false.
|
102
|
-
## * :required: If set to true, the argument must be provided on the
|
103
|
-
## commandline.
|
104
|
-
## * :multi: If set to true, allows multiple instances of the
|
105
|
-
## option. Otherwise, only a single instance of the option is
|
106
|
-
## allowed.
|
86
|
+
## Takes the following optional arguments:
|
87
|
+
##
|
88
|
+
## [+:long+] Specify the long form of the argument, i.e. the form with two dashes. If unspecified, will be automatically derived based on the argument name by turning the +name+ option into a string, and replacing any _'s by -'s.
|
89
|
+
## [+:short+] Specify the short form of the argument, i.e. the form with one dash. If unspecified, will be automatically derived from +name+.
|
90
|
+
## [+:type+] Require that the argument take a parameter or parameters of type +type+. For a single parameter, the value can be a member of +SINGLE_ARG_TYPES+, or a corresponding Ruby class (e.g. +Integer+ for +:int+). For multiple parameters, the value can be any member of +MULTI_ARG_TYPES+ constant. If unset, the default argument type is +:flag+, meaning that the argument does not take a parameter. The specification of +:type+ is not necessary if +:default+ is given.
|
91
|
+
## [+:default+] Set the default value for an argument. Without a default value, the hash returned by #parse (and thus Trollop#options) will have a +nil+ value for this key unless the option is set on the commandline. The argument type is derived automatically from the class of the default value given, if any. Specifying a +:flag+ argument on the commandline whose default value is +true+ will result in a value of +false+.
|
92
|
+
## [+:required+] If set to +true+, the argument must be provided on the commandline.
|
93
|
+
## [+:multi+] If set to +true+, allows multiple instances of the option on the commandline. Otherwise, only a single instance of the option is allowed.
|
107
94
|
def opt name, desc="", opts={}
|
108
95
|
raise ArgumentError, "you already have an argument named '#{name}'" if @specs.member? name
|
109
96
|
|
110
97
|
## fill in :type
|
111
|
-
opts[:type] =
|
98
|
+
opts[:type] = # normalize
|
112
99
|
case opts[:type]
|
113
|
-
when :
|
114
|
-
when :
|
115
|
-
when :
|
116
|
-
when :
|
117
|
-
when :
|
118
|
-
when :double, :float; :float
|
119
|
-
when :doubles, :floats; :floats
|
100
|
+
when :boolean, :bool; :flag
|
101
|
+
when :integer; :int
|
102
|
+
when :integers; :ints
|
103
|
+
when :double; :float
|
104
|
+
when :doubles; :floats
|
120
105
|
when Class
|
121
106
|
case opts[:type].to_s # sigh... there must be a better way to do this
|
122
107
|
when 'TrueClass', 'FalseClass'; :flag
|
123
108
|
when 'String'; :string
|
124
109
|
when 'Integer'; :int
|
125
110
|
when 'Float'; :float
|
111
|
+
when 'IO'; :io
|
126
112
|
else
|
127
113
|
raise ArgumentError, "unsupported argument type '#{opts[:type].class.name}'"
|
128
114
|
end
|
129
115
|
when nil; nil
|
130
116
|
else
|
131
117
|
raise ArgumentError, "unsupported argument type '#{opts[:type]}'" unless TYPES.include?(opts[:type])
|
118
|
+
opts[:type]
|
132
119
|
end
|
133
120
|
|
134
121
|
type_from_default =
|
@@ -137,6 +124,7 @@ class Parser
|
|
137
124
|
when Numeric; :float
|
138
125
|
when TrueClass, FalseClass; :flag
|
139
126
|
when String; :string
|
127
|
+
when IO; :io
|
140
128
|
when Array
|
141
129
|
if opts[:default].empty?
|
142
130
|
raise ArgumentError, "multiple argument type cannot be deduced from an empty array for '#{opts[:default][0].class.name}'"
|
@@ -145,6 +133,7 @@ class Parser
|
|
145
133
|
when Integer; :ints
|
146
134
|
when Numeric; :floats
|
147
135
|
when String; :strings
|
136
|
+
when IO; :ios
|
148
137
|
else
|
149
138
|
raise ArgumentError, "unsupported multiple argument type '#{opts[:default][0].class.name}'"
|
150
139
|
end
|
@@ -206,11 +195,12 @@ class Parser
|
|
206
195
|
end
|
207
196
|
|
208
197
|
## Sets the version string. If set, the user can request the version
|
209
|
-
## on the commandline. Should be of the form "<program name>
|
198
|
+
## on the commandline. Should probably be of the form "<program name>
|
210
199
|
## <version number>".
|
211
200
|
def version s=nil; @version = s if s; @version end
|
212
201
|
|
213
|
-
## Adds text to the help display.
|
202
|
+
## Adds text to the help display. Can be interspersed with calls to
|
203
|
+
## #opt to build a multi-section help page.
|
214
204
|
def banner s; @order << [:text, s] end
|
215
205
|
alias :text :banner
|
216
206
|
|
@@ -228,19 +218,23 @@ class Parser
|
|
228
218
|
@constraints << [:conflicts, syms]
|
229
219
|
end
|
230
220
|
|
231
|
-
## Defines a set of words which cause parsing to terminate when
|
232
|
-
## such that any options to the left of the word are
|
233
|
-
## options to the right of the word are left
|
221
|
+
## Defines a set of words which cause parsing to terminate when
|
222
|
+
## encountered, such that any options to the left of the word are
|
223
|
+
## parsed as usual, and options to the right of the word are left
|
224
|
+
## intact.
|
234
225
|
##
|
235
|
-
## A typical use case would be for subcommand support, where these
|
236
|
-
## set to the list of subcommands. A subsequent Trollop
|
237
|
-
## then be used to parse subcommand options
|
226
|
+
## A typical use case would be for subcommand support, where these
|
227
|
+
## would be set to the list of subcommands. A subsequent Trollop
|
228
|
+
## invocation would then be used to parse subcommand options, after
|
229
|
+
## shifting the subcommand off of ARGV.
|
238
230
|
def stop_on *words
|
239
231
|
@stop_words = [*words].flatten
|
240
232
|
end
|
241
233
|
|
242
|
-
## Similar to stop_on, but stops on any unknown word when encountered
|
243
|
-
## it is a parameter for an argument).
|
234
|
+
## Similar to #stop_on, but stops on any unknown word when encountered
|
235
|
+
## (unless it is a parameter for an argument). This is useful for
|
236
|
+
## cases where you don't know the set of subcommands ahead of time,
|
237
|
+
## i.e., without first parsing the global options.
|
244
238
|
def stop_on_unknown
|
245
239
|
@stop_on_unknown = true
|
246
240
|
end
|
@@ -317,7 +311,8 @@ class Parser
|
|
317
311
|
remains
|
318
312
|
end
|
319
313
|
|
320
|
-
|
314
|
+
## Parses the commandline. Typically called by Trollop::options.
|
315
|
+
def parse cmdline=ARGV
|
321
316
|
vals = {}
|
322
317
|
required = {}
|
323
318
|
|
@@ -406,6 +401,8 @@ class Parser
|
|
406
401
|
vals[sym] = params.map { |pg| pg.map { |p| parse_float_parameter p, arg } }
|
407
402
|
when :string, :strings
|
408
403
|
vals[sym] = params.map { |pg| pg.map { |p| p.to_s } }
|
404
|
+
when :io, :ios
|
405
|
+
vals[sym] = params.map { |pg| pg.map { |p| parse_io_parameter p, arg } }
|
409
406
|
end
|
410
407
|
|
411
408
|
if SINGLE_ARG_TYPES.include?(opts[:type])
|
@@ -433,6 +430,19 @@ class Parser
|
|
433
430
|
param.to_f
|
434
431
|
end
|
435
432
|
|
433
|
+
def parse_io_parameter param, arg #:nodoc:
|
434
|
+
case param
|
435
|
+
when /^(stdin|-)$/i; $stdin
|
436
|
+
else
|
437
|
+
require 'open-uri'
|
438
|
+
begin
|
439
|
+
open param
|
440
|
+
rescue SystemCallError => e
|
441
|
+
raise CommandlineError, "file or url for option '#{arg}' cannot be opened: #{e.message}"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
436
446
|
def collect_argument_parameters args, start_at #:nodoc:
|
437
447
|
params = []
|
438
448
|
pos = start_at
|
@@ -446,21 +456,22 @@ class Parser
|
|
446
456
|
def width #:nodoc:
|
447
457
|
@width ||=
|
448
458
|
if $stdout.tty?
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
459
|
+
if `stty size` =~ /^(\d+) (\d+)$/
|
460
|
+
$2.to_i
|
461
|
+
else
|
462
|
+
begin
|
463
|
+
require 'curses'
|
464
|
+
Curses::init_screen
|
465
|
+
x = Curses::cols
|
466
|
+
Curses::close_screen
|
467
|
+
x
|
468
|
+
rescue Exception
|
469
|
+
end
|
457
470
|
end
|
458
|
-
|
459
|
-
80
|
460
|
-
end
|
471
|
+
end || 80
|
461
472
|
end
|
462
473
|
|
463
|
-
## Print the help message to
|
474
|
+
## Print the help message to +stream+.
|
464
475
|
def educate stream=$stdout
|
465
476
|
width # just calculate it now; otherwise we have to be careful not to
|
466
477
|
# call this unless the cursor's at the beginning of a line.
|
@@ -477,6 +488,8 @@ class Parser
|
|
477
488
|
when :strings; " <s+>"
|
478
489
|
when :float; " <f>"
|
479
490
|
when :floats; " <f+>"
|
491
|
+
when :io; " <filename/uri>"
|
492
|
+
when :ios; " <filename/uri+>"
|
480
493
|
end
|
481
494
|
end
|
482
495
|
|
@@ -552,15 +565,15 @@ end
|
|
552
565
|
|
553
566
|
## The top-level entry method into Trollop. Creates a Parser object,
|
554
567
|
## passes the block to it, then parses +args+ with it, handling any
|
555
|
-
## errors or requests for help or version information appropriately
|
556
|
-
##
|
557
|
-
##
|
568
|
+
## errors or requests for help or version information appropriately (and
|
569
|
+
## then exiting). Modifies +args+ in place. Returns a hash of option
|
570
|
+
## values.
|
558
571
|
##
|
559
|
-
## The block passed in should contain
|
560
|
-
## (Parser#opt),
|
561
|
-
## probably a call to version (Parser#version).
|
572
|
+
## The block passed in should contain zero or more calls to +opt+
|
573
|
+
## (Parser#opt), zero or more calls to +text+ (Parser#text), and
|
574
|
+
## probably a call to +version+ (Parser#version).
|
562
575
|
##
|
563
|
-
## See the
|
576
|
+
## See the examples at http://trollop.rubyforge.org.
|
564
577
|
def options args = ARGV, *a, &b
|
565
578
|
@p = Parser.new(*a, &b)
|
566
579
|
begin
|
@@ -612,3 +625,4 @@ end
|
|
612
625
|
module_function :options, :die
|
613
626
|
|
614
627
|
end # module
|
628
|
+
|
data/test/test_trollop.rb
CHANGED
@@ -870,6 +870,28 @@ EOM
|
|
870
870
|
assert_equal true, opts[physicist]
|
871
871
|
end
|
872
872
|
end
|
873
|
+
|
874
|
+
def test_io_arg_type
|
875
|
+
@p.opt :arg, "desc", :type => :io
|
876
|
+
@p.opt :arg2, "desc", :type => IO
|
877
|
+
@p.opt :arg3, "desc", :default => $stdout
|
878
|
+
|
879
|
+
opts = nil
|
880
|
+
assert_nothing_raised { opts = @p.parse() }
|
881
|
+
assert_equal $stdout, opts[:arg3]
|
882
|
+
|
883
|
+
assert_nothing_raised { opts = @p.parse %w(--arg /dev/null) }
|
884
|
+
assert_kind_of File, opts[:arg]
|
885
|
+
assert_equal "/dev/null", opts[:arg].path
|
886
|
+
|
887
|
+
assert_nothing_raised { opts = @p.parse %w(--arg2 http://google.com/) }
|
888
|
+
assert_kind_of StringIO, opts[:arg2]
|
889
|
+
|
890
|
+
assert_nothing_raised { opts = @p.parse %w(--arg3 stdin) }
|
891
|
+
assert_equal $stdin, opts[:arg3]
|
892
|
+
|
893
|
+
assert_raises(CommandlineError) { opts = @p.parse %w(--arg /fdasfasef/fessafef/asdfasdfa/fesasf) }
|
894
|
+
end
|
873
895
|
end
|
874
896
|
|
875
897
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trollop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.10"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Morgan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-10-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,9 +20,9 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.
|
23
|
+
version: 1.8.0
|
24
24
|
version:
|
25
|
-
description:
|
25
|
+
description: == DESCRIPTION Trollop is a commandline option parser for Ruby that just gets out of your way. One line of code per option is all you need to write. For that, you get a nice automatically-generated help page, robust option parsing, command subcompletion, and sensible defaults for everything you don't specify. * A burning desire to write less code. == INSTALL * gem install trollop == LICENSE Copyright (c) 2008 William Morgan. Trollop is distributed under the same terms as Ruby.
|
26
26
|
email: wmorgan-trollop@masanjin.net
|
27
27
|
executables: []
|
28
28
|
|