trollop 1.10 → 1.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/README.txt +1 -1
- data/Rakefile +8 -4
- data/lib/trollop.rb +82 -14
- data/test/test_trollop.rb +61 -2
- metadata +4 -13
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 1.10.1 / 2008-10-22
|
2
|
+
* Options hash now responds to method calls as well as standard hash lookup.
|
3
|
+
* Default values for multi-occurrence parameters now autoboxed.
|
4
|
+
* The relationship between multi-value, multi-occurrence, and default values
|
5
|
+
improved and explained.
|
6
|
+
* Documentation improvements.
|
7
|
+
|
1
8
|
== 1.10 / 2008-10-21
|
2
9
|
* Added :io type for parameters that point to IO streams (filenames, URIs, etc).
|
3
10
|
* For screen size detection, first try `stty size` before loading Curses.
|
data/README.txt
CHANGED
data/Rakefile
CHANGED
@@ -7,8 +7,8 @@ $:.unshift "lib"
|
|
7
7
|
require 'trollop'
|
8
8
|
|
9
9
|
class Hoe
|
10
|
-
def
|
11
|
-
end
|
10
|
+
def extra_dev_deps; @extra_dev_deps.reject { |x| x[0] == "hoe" } end
|
11
|
+
end
|
12
12
|
|
13
13
|
Hoe.new('trollop', Trollop::VERSION) do |p|
|
14
14
|
p.rubyforge_name = 'trollop'
|
@@ -25,8 +25,12 @@ task :upload_webpage => WWW_FILES do |t|
|
|
25
25
|
sh "rsync -Paz -essh #{t.prerequisites * ' '} wmorgan@rubyforge.org:/var/www/gforge-projects/trollop/"
|
26
26
|
end
|
27
27
|
|
28
|
-
task :
|
29
|
-
sh "
|
28
|
+
task :rdoc do |t|
|
29
|
+
sh "rdoc lib README.txt History.txt"
|
30
|
+
end
|
31
|
+
|
32
|
+
task :upload_docs => [:rdoc] do |t|
|
33
|
+
sh "rsync -az -essh doc/* wmorgan@rubyforge.org:/var/www/gforge-projects/trollop/trollop/"
|
30
34
|
end
|
31
35
|
|
32
36
|
# vim: syntax=ruby
|
data/lib/trollop.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
module Trollop
|
7
7
|
|
8
|
-
VERSION = "1.10"
|
8
|
+
VERSION = "1.10.1"
|
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,7 +26,7 @@ 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
|
29
|
+
## will be handled internally by Trollop::options. In this case, only the
|
30
30
|
## #opt, #banner and #version, #depends, and #conflicts methods will
|
31
31
|
## typically be called.
|
32
32
|
##
|
@@ -79,18 +79,43 @@ class Parser
|
|
79
79
|
end
|
80
80
|
|
81
81
|
## Define an option. +name+ is the option name, a unique identifier
|
82
|
-
## for the option that you will use internally
|
83
|
-
##
|
84
|
-
## in help messages.
|
82
|
+
## for the option that you will use internally, which should be a
|
83
|
+
## symbol or a string. +desc+ is a string description which will be
|
84
|
+
## displayed in help messages.
|
85
85
|
##
|
86
86
|
## Takes the following optional arguments:
|
87
87
|
##
|
88
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
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
|
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-argument 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 a +: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 argument is given on the commandline. The argument type is derived automatically from the class of the default value given, so specifying a +:type+ is not necessary if a +:default+ is given. (But see below for an important caveat when +:multi+: is specified too.) If the argument is a flag, and the default is set to +true+, then if it is specified on the the commandline the value will be +false+.
|
92
92
|
## [+:required+] If set to +true+, the argument must be provided on the commandline.
|
93
|
-
## [+:multi+] If set to +true+, allows multiple
|
93
|
+
## [+:multi+] If set to +true+, allows multiple occurrences of the option on the commandline. Otherwise, only a single instance of the option is allowed. (Note that this is different from taking multiple parameters. See below.)
|
94
|
+
##
|
95
|
+
## Note that there are two types of argument multiplicity: an argument
|
96
|
+
## can take multiple values, e.g. "--arg 1 2 3". An argument can also
|
97
|
+
## be allowed to occur multiple times, e.g. "--arg 1 --arg 2".
|
98
|
+
##
|
99
|
+
## Arguments that take multiple values should have a +:type+ parameter
|
100
|
+
## drawn from +MULTI_ARG_TYPES+ (e.g. +:strings+), or a +:default:+
|
101
|
+
## value of an array of the correct type (e.g. [String]). The
|
102
|
+
## value of this argument will be an array of the parameters on the
|
103
|
+
## commandline.
|
104
|
+
##
|
105
|
+
## Arguments that can occur multiple times should be marked with
|
106
|
+
## +:multi+ => +true+. The value of this argument will also be an array.
|
107
|
+
##
|
108
|
+
## These two attributes can be combined (e.g. +:type+ => +:strings+,
|
109
|
+
## +:multi+ => +true+), in which case the value of the argument will be
|
110
|
+
## an array of arrays.
|
111
|
+
##
|
112
|
+
## There's one ambiguous case to be aware of: when +:multi+: is true and a
|
113
|
+
## +:default+ is set to an array (of something), it's ambiguous whether this
|
114
|
+
## is a multi-value argument as well as a multi-occurrence argument.
|
115
|
+
## In thise case, Trollop assumes that it's not a multi-value argument.
|
116
|
+
## If you want a multi-value, multi-occurrence argument with a default
|
117
|
+
## value, you must specify +:type+ as well.
|
118
|
+
|
94
119
|
def opt name, desc="", opts={}
|
95
120
|
raise ArgumentError, "you already have an argument named '#{name}'" if @specs.member? name
|
96
121
|
|
@@ -118,8 +143,19 @@ class Parser
|
|
118
143
|
opts[:type]
|
119
144
|
end
|
120
145
|
|
146
|
+
## for options with :multi => true, an array default doesn't imply
|
147
|
+
## a multi-valued argument. for that you have to specify a :type
|
148
|
+
## as well. (this is how we disambiguate an ambiguous situation;
|
149
|
+
## see the docs for Parser#opt for details.)
|
150
|
+
disambiguated_default =
|
151
|
+
if opts[:multi] && opts[:default].is_a?(Array) && !opts[:type]
|
152
|
+
opts[:default].first
|
153
|
+
else
|
154
|
+
opts[:default]
|
155
|
+
end
|
156
|
+
|
121
157
|
type_from_default =
|
122
|
-
case
|
158
|
+
case disambiguated_default
|
123
159
|
when Integer; :int
|
124
160
|
when Numeric; :float
|
125
161
|
when TrueClass, FalseClass; :flag
|
@@ -144,7 +180,7 @@ class Parser
|
|
144
180
|
|
145
181
|
raise ArgumentError, ":type specification and default type don't match" if opts[:type] && type_from_default && opts[:type] != type_from_default
|
146
182
|
|
147
|
-
opts[:type] =
|
183
|
+
opts[:type] = opts[:type] || type_from_default || :flag
|
148
184
|
|
149
185
|
## fill in :long
|
150
186
|
opts[:long] = opts[:long] ? opts[:long].to_s : name.to_s.gsub("_", "-")
|
@@ -184,6 +220,9 @@ class Parser
|
|
184
220
|
## fill in :default for flags
|
185
221
|
opts[:default] = false if opts[:type] == :flag && opts[:default].nil?
|
186
222
|
|
223
|
+
## autobox :default for :multi (multi-occurrence) arguments
|
224
|
+
opts[:default] = [opts[:default]] if opts[:default] && opts[:multi] && !opts[:default].is_a?(Array)
|
225
|
+
|
187
226
|
## fill in :multi
|
188
227
|
opts[:multi] ||= false
|
189
228
|
|
@@ -417,6 +456,12 @@ class Parser
|
|
417
456
|
# else: multiple options, with multiple parameters
|
418
457
|
end
|
419
458
|
|
459
|
+
## allow openstruct-style accessors
|
460
|
+
class << vals
|
461
|
+
def method_missing(m, *args)
|
462
|
+
self[m] || self[m.to_s]
|
463
|
+
end
|
464
|
+
end
|
420
465
|
vals
|
421
466
|
end
|
422
467
|
|
@@ -509,16 +554,27 @@ class Parser
|
|
509
554
|
|
510
555
|
spec = @specs[opt]
|
511
556
|
stream.printf " %#{leftcol_width}s: ", left[opt]
|
512
|
-
desc = spec[:desc] +
|
557
|
+
desc = spec[:desc] + begin
|
558
|
+
default_s = case spec[:default]
|
559
|
+
when $stdout; "<stdout>"
|
560
|
+
when $stdin; "<stdin>"
|
561
|
+
when $stderr; "<stderr>"
|
562
|
+
when Array
|
563
|
+
spec[:default].join(", ")
|
564
|
+
else
|
565
|
+
spec[:default].to_s
|
566
|
+
end
|
567
|
+
|
513
568
|
if spec[:default]
|
514
569
|
if spec[:desc] =~ /\.$/
|
515
|
-
" (Default: #{
|
570
|
+
" (Default: #{default_s})"
|
516
571
|
else
|
517
|
-
" (default: #{
|
572
|
+
" (default: #{default_s})"
|
518
573
|
end
|
519
574
|
else
|
520
575
|
""
|
521
576
|
end
|
577
|
+
end
|
522
578
|
stream.puts wrap(desc, :width => width - rightcol_start - 1, :prefix => rightcol_start)
|
523
579
|
end
|
524
580
|
end
|
@@ -573,7 +629,19 @@ end
|
|
573
629
|
## (Parser#opt), zero or more calls to +text+ (Parser#text), and
|
574
630
|
## probably a call to +version+ (Parser#version).
|
575
631
|
##
|
576
|
-
##
|
632
|
+
## Example:
|
633
|
+
##
|
634
|
+
## require 'trollop'
|
635
|
+
## opts = Trollop::options do
|
636
|
+
## opt :monkey, "Use monkey mode" # a flag --monkey, defaulting to false
|
637
|
+
## opt :goat, "Use goat mode", :default => true # a flag --goat, defaulting to true
|
638
|
+
## opt :num_limbs, "Number of limbs", :default => 4 # an integer --num-limbs <i>, defaulting to 4
|
639
|
+
## opt :num_thumbs, "Number of thumbs", :type => :int # an integer --num-thumbs <i>, defaulting to nil
|
640
|
+
## end
|
641
|
+
##
|
642
|
+
## p opts # returns a hash: { :monkey => false, :goat => true, :num_limbs => 4, :num_thumbs => nil }
|
643
|
+
##
|
644
|
+
## See more examples at http://trollop.rubyforge.org.
|
577
645
|
def options args = ARGV, *a, &b
|
578
646
|
@p = Parser.new(*a, &b)
|
579
647
|
begin
|
data/test/test_trollop.rb
CHANGED
@@ -884,14 +884,73 @@ EOM
|
|
884
884
|
assert_kind_of File, opts[:arg]
|
885
885
|
assert_equal "/dev/null", opts[:arg].path
|
886
886
|
|
887
|
-
|
888
|
-
|
887
|
+
#TODO: move to mocks
|
888
|
+
#assert_nothing_raised { opts = @p.parse %w(--arg2 http://google.com/) }
|
889
|
+
#assert_kind_of StringIO, opts[:arg2]
|
889
890
|
|
890
891
|
assert_nothing_raised { opts = @p.parse %w(--arg3 stdin) }
|
891
892
|
assert_equal $stdin, opts[:arg3]
|
892
893
|
|
893
894
|
assert_raises(CommandlineError) { opts = @p.parse %w(--arg /fdasfasef/fessafef/asdfasdfa/fesasf) }
|
894
895
|
end
|
896
|
+
|
897
|
+
def test_openstruct_style_access
|
898
|
+
@p.opt "arg1", "desc", :type => :int
|
899
|
+
@p.opt :arg2, "desc", :type => :int
|
900
|
+
|
901
|
+
opts = @p.parse(%w(--arg1 3 --arg2 4))
|
902
|
+
|
903
|
+
assert_nothing_raised { opts.arg1 }
|
904
|
+
assert_nothing_raised { opts.arg2 }
|
905
|
+
assert_equal 3, opts.arg1
|
906
|
+
assert_equal 4, opts.arg2
|
907
|
+
end
|
908
|
+
|
909
|
+
def test_multi_args_autobox_defaults
|
910
|
+
@p.opt :arg1, "desc", :default => "hello", :multi => true
|
911
|
+
@p.opt :arg2, "desc", :default => ["hello"], :multi => true
|
912
|
+
|
913
|
+
opts = @p.parse
|
914
|
+
assert_equal ["hello"], opts[:arg1]
|
915
|
+
assert_equal ["hello"], opts[:arg2]
|
916
|
+
|
917
|
+
opts = @p.parse %w(--arg1 hello)
|
918
|
+
assert_equal ["hello"], opts[:arg1]
|
919
|
+
assert_equal ["hello"], opts[:arg2]
|
920
|
+
|
921
|
+
opts = @p.parse %w(--arg1 hello --arg1 there)
|
922
|
+
assert_equal ["hello", "there"], opts[:arg1]
|
923
|
+
end
|
924
|
+
|
925
|
+
def test_ambigious_multi_plus_array_default_resolved_as_specified_by_documentation
|
926
|
+
@p.opt :arg1, "desc", :default => ["potato"], :multi => true
|
927
|
+
@p.opt :arg2, "desc", :default => ["potato"], :multi => true, :type => :strings
|
928
|
+
@p.opt :arg3, "desc", :default => ["potato"]
|
929
|
+
@p.opt :arg4, "desc", :default => ["potato", "rhubarb"], :short => :none, :multi => true
|
930
|
+
|
931
|
+
## arg1 should be multi-occurring but not multi-valued
|
932
|
+
opts = @p.parse %w(--arg1 one two)
|
933
|
+
assert_equal ["one"], opts[:arg1]
|
934
|
+
assert_equal ["two"], @p.leftovers
|
935
|
+
|
936
|
+
opts = @p.parse %w(--arg1 one --arg1 two)
|
937
|
+
assert_equal ["one", "two"], opts[:arg1]
|
938
|
+
assert_equal [], @p.leftovers
|
939
|
+
|
940
|
+
## arg2 should be multi-valued and multi-occurring
|
941
|
+
opts = @p.parse %w(--arg2 one two)
|
942
|
+
assert_equal [["one", "two"]], opts[:arg2]
|
943
|
+
assert_equal [], @p.leftovers
|
944
|
+
|
945
|
+
## arg3 should be multi-valued but not multi-occurring
|
946
|
+
opts = @p.parse %w(--arg3 one two)
|
947
|
+
assert_equal ["one", "two"], opts[:arg3]
|
948
|
+
assert_equal [], @p.leftovers
|
949
|
+
|
950
|
+
## arg4 should be multi-valued but not multi-occurring
|
951
|
+
opts = @p.parse %w()
|
952
|
+
assert_equal ["potato", "rhubarb"], opts[:arg4]
|
953
|
+
end
|
895
954
|
end
|
896
955
|
|
897
956
|
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:
|
4
|
+
version: 1.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Morgan
|
@@ -9,19 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-10-
|
12
|
+
date: 2008-10-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: hoe
|
17
|
-
type: :development
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.8.0
|
24
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
25
16
|
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
17
|
email: wmorgan-trollop@masanjin.net
|
27
18
|
executables: []
|